Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
Solved

# SQL Query to sum amounts, and convert into calendar months

Posted on 2014-03-25
Medium Priority
234 Views
Hi,

I need to create a an SQL query which takes the information from the main "Projects" table, and then uses column "WBS1" to join onto 3 other tables "AP","AR","EX".
The 3 AP,AR,EX tables have the information stored per transaction date.

The requirement is to return the sum(AP+AR+EX) Per WBS1 but for each calendar month.

It is also important that if there has been no transactions for the month , it returns <null> rather than 0

The attached PDF hopefully explains a little more.

SQL-WBS1.pdf
0
Question by:supertramp4
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 2
• 2

LVL 35

Expert Comment

ID: 39953758
E.g.
``````DECLARE @A TABLE ( A1 INT, A2 INT );
DECLARE @B TABLE ( B1 INT, B2 DATE, B3 INT );
DECLARE @C TABLE ( C1 INT, C2 DATE, C3 INT );

INSERT  INTO @A
VALUES  ( 1, 1 ),
( 2, 20 ),
( 3, 300 );

INSERT  INTO @B
VALUES  ( 1, '19000101', 1 ),
( 1, '19000201', 2 ),
( 1, '19000301', 3 ),
( 2, '19000101', 1 ),
( 2, '19000101', 2 );

INSERT  INTO @C
VALUES  ( 1, '19000101', 1 ),
( 1, '19000401', 40 ),
( 3, '19000103', 300 );

WITH    Data
AS ( SELECT   A.A1 ,
A.A2 ,
Q.Q2 ,
Q.Q3
FROM     @A A
INNER JOIN ( SELECT B1 ,
MONTH(B2) ,
B3
FROM   @B
UNION ALL
SELECT C1 ,
MONTH(C2) ,
C3
FROM   @C
) Q ( Q1, Q2, Q3 ) ON A.A1 = Q.Q1
)
SELECT  *
FROM    Data PIVOT ( SUM(Q3) FOR Q2 IN ( [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12] ) ) P;
``````
0

LVL 70

Accepted Solution

Scott Pletcher earned 2000 total points
ID: 39954111
/* Data Setup Only, NOT main code */

IF OBJECT_ID('tempdb..#projects') IS NOT NULL
DROP TABLE #projects
CREATE TABLE #projects (
WBS1 varchar(30),
Status varchar(10),
Reference varchar(30)
)
INSERT INTO #projects
SELECT 'wbs123', 'Active', 'AQ73' UNION ALL
SELECT 'Wbs456', 'Active', 'ZZ74' UNION ALL
SELECT 'Wbs789', 'inactive', 'WR89'

IF OBJECT_ID('tempdb..#AP') IS NOT NULL
DROP TABLE #AP
CREATE TABLE #AP (
WBS1 varchar(30),
Date datetime,
Amount money
)
INSERT INTO #AP
SELECT 'wbs123', '01-jan-2013', £1.00 UNION ALL
SELECT 'Wbs123', '03-mar-2013', £2.00 UNION ALL
SELECT 'Wbs456', '03-mar-2013', £4.56

IF OBJECT_ID('tempdb..#AR') IS NOT NULL
DROP TABLE #AR
CREATE TABLE #AR (
WBS1 varchar(30),
Date datetime,
Amount money
)
INSERT INTO #AR
SELECT 'wbs123', '01-jan-2013', £1.00 UNION ALL
SELECT 'Wbs123', '03-mar-2013', £2.00

IF OBJECT_ID('tempdb..#EX') IS NOT NULL
DROP TABLE #EX
CREATE TABLE #EX (
WBS1 varchar(30),
Date datetime,
Amount money
)
INSERT INTO #EX
SELECT 'wbs123', '01-Mar-2013', £1.00

-- MAIN CODE BEGINS HERE

DECLARE @start_date datetime
SET @start_date = '20130101' --<<-- set to desired starting date (does not have to be Jan 1)

---------------------------------------------------------------------------------

-- force @start_date to be the first day of the month at midnight
SET @start_date = DATEADD(MONTH, DATEDIFF(MONTH, 0, @start_date), 0)

SELECT
p.WBS1, p.Reference,
NULLIF(SUM(CASE WHEN MONTH(dates.Date_Month) = 01 THEN ISNULL(ap.Amount_Month, 0) +
ISNULL(ar.Amount_Month, 0) + ISNULL(ex.Amount_Month, 0) END), 0) AS Jan,
NULLIF(SUM(CASE WHEN MONTH(dates.Date_Month) = 02 THEN ISNULL(ap.Amount_Month, 0) +
ISNULL(ar.Amount_Month, 0) + ISNULL(ex.Amount_Month, 0) END), 0) AS Feb,
NULLIF(SUM(CASE WHEN MONTH(dates.Date_Month) = 03 THEN ISNULL(ap.Amount_Month, 0) +
ISNULL(ar.Amount_Month, 0) + ISNULL(ex.Amount_Month, 0) END), 0) AS Mar,
NULLIF(SUM(CASE WHEN MONTH(dates.Date_Month) = 04 THEN ISNULL(ap.Amount_Month, 0) +
ISNULL(ar.Amount_Month, 0) + ISNULL(ex.Amount_Month, 0) END), 0) AS Apr,
NULLIF(SUM(CASE WHEN MONTH(dates.Date_Month) = 05 THEN ISNULL(ap.Amount_Month, 0) +
ISNULL(ar.Amount_Month, 0) + ISNULL(ex.Amount_Month, 0) END), 0) AS May,
NULLIF(SUM(CASE WHEN MONTH(dates.Date_Month) = 06 THEN ISNULL(ap.Amount_Month, 0) +
ISNULL(ar.Amount_Month, 0) + ISNULL(ex.Amount_Month, 0) END), 0) AS Jun,
NULLIF(SUM(CASE WHEN MONTH(dates.Date_Month) = 07 THEN ISNULL(ap.Amount_Month, 0) +
ISNULL(ar.Amount_Month, 0) + ISNULL(ex.Amount_Month, 0) END), 0) AS Jul,
NULLIF(SUM(CASE WHEN MONTH(dates.Date_Month) = 08 THEN ISNULL(ap.Amount_Month, 0) +
ISNULL(ar.Amount_Month, 0) + ISNULL(ex.Amount_Month, 0) END), 0) AS Aug,
NULLIF(SUM(CASE WHEN MONTH(dates.Date_Month) = 09 THEN ISNULL(ap.Amount_Month, 0) +
ISNULL(ar.Amount_Month, 0) + ISNULL(ex.Amount_Month, 0) END), 0) AS Sep,
NULLIF(SUM(CASE WHEN MONTH(dates.Date_Month) = 10 THEN ISNULL(ap.Amount_Month, 0) +
ISNULL(ar.Amount_Month, 0) + ISNULL(ex.Amount_Month, 0) END), 0) AS Oct,
NULLIF(SUM(CASE WHEN MONTH(dates.Date_Month) = 11 THEN ISNULL(ap.Amount_Month, 0) +
ISNULL(ar.Amount_Month, 0) + ISNULL(ex.Amount_Month, 0) END), 0) AS Nov,
NULLIF(SUM(CASE WHEN MONTH(dates.Date_Month) = 12 THEN ISNULL(ap.Amount_Month, 0) +
ISNULL(ar.Amount_Month, 0) + ISNULL(ex.Amount_Month, 0) END), 0) AS Dec
FROM #projects p
CROSS JOIN (
--DECLARE @start_date datetime SET @start_date = '20130101'
SELECT DATEADD(MONTH, month_counter, @start_date) AS Date_Month
FROM (
SELECT 00 AS month_counter UNION ALL SELECT 01 UNION ALL SELECT 02 UNION ALL SELECT 03 UNION ALL
SELECT 04 UNION ALL SELECT 05 UNION ALL SELECT 06 UNION ALL SELECT 07 UNION ALL
SELECT 08 UNION ALL SELECT 09 UNION ALL SELECT 10 UNION ALL SELECT 11
) AS month_counters
) AS dates
LEFT OUTER JOIN (
--DECLARE @start_date datetime SET @start_date = '20130101'
SELECT
WBS1,
DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0) AS Date_Month,
SUM(Amount) AS Amount_Month
FROM #AP
WHERE
Date >= @start_date AND
GROUP BY
WBS1, DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)
) AS ap ON
ap.WBS1 = p.WBS1 AND
ap.Date_Month = dates.Date_Month
LEFT OUTER JOIN (
--DECLARE @start_date datetime SET @start_date = '20130101'
SELECT
WBS1,
DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0) AS Date_Month,
SUM(Amount) AS Amount_Month
FROM #AR
WHERE
Date >= @start_date AND
GROUP BY
WBS1, DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)
) AS ar ON
ar.WBS1 = p.WBS1 AND
ar.Date_Month = dates.Date_Month
LEFT OUTER JOIN (
SELECT
WBS1,
DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0) AS Date_Month,
SUM(Amount) AS Amount_Month
FROM #EX
WHERE
Date >= @start_date AND
GROUP BY
WBS1, DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)
) AS ex ON
ex.WBS1 = p.WBS1 AND
ex.Date_Month = dates.Date_Month
WHERE
p.Status = 'Active'
GROUP BY
p.WBS1, p.Reference
0

Author Comment

ID: 39955309
hi both,

thanks for the examples, I am out of the office today, but will try as soon as I can.
0

Author Closing Comment

ID: 39971598
Nice solution, and this is now working will in our system
0

LVL 35

Expert Comment

ID: 39971920
My solution is shorter...

``````WITH    Data
AS ( SELECT   A.WBS1 ,
A.Reference ,
Q.MonthDate ,
Q.Amount
FROM     #Projects A
INNER JOIN ( SELECT WBS1 ,
MONTH([Date]) MonthDate ,
Amount
FROM   #AP
UNION ALL
SELECT WBS1 ,
MONTH([Date]) MonthDate ,
Amount
FROM   #AR
UNION ALL
SELECT WBS1 ,
MONTH([Date]) MonthDate ,
Amount
FROM   #EX
) Q ON A.WBS1 = Q.WBS1
WHERE    A.[Status] = 'Active'
)
SELECT  *
FROM    Data PIVOT ( SUM(Amount) FOR MonthDate IN ( [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12] ) ) P;
``````

Using one more CTE for clarity:

``````WITH    RawData
AS ( SELECT   WBS1 ,
MONTH([Date]) MonthDate ,
Amount
FROM     #AP
UNION ALL
SELECT   WBS1 ,
MONTH([Date]) MonthDate ,
Amount
FROM     #AR
UNION ALL
SELECT   WBS1 ,
MONTH([Date]) MonthDate ,
Amount
FROM     #EX
),
JoinedData
AS ( SELECT   A.WBS1 ,
A.Reference ,
Q.MonthDate ,
Q.Amount
FROM     #Projects A
INNER JOIN RawData Q ON A.WBS1 = Q.WBS1
WHERE    A.[Status] = 'Active'
)
SELECT  *
FROM    JoinedData PIVOT ( SUM(Amount) FOR MonthDate IN ( [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12] ) ) P;
``````
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Ever needed a SQL 2008 Database replicated/mirrored/log shipped on another server but you can't take the downtime inflicted by initial snapshot or disconnect while T-logs are restored or mirror applied? You can use SQL Server Initialize from Backup…
Ever wondered why sometimes your SQL Server is slow or unresponsive with connections spiking up but by the time you go in, all is well? The following article will show you how to install and configure a SQL job that will send you email alerts includ…
Familiarize people with the process of retrieving data from SQL Server using an Access pass-thru query. Microsoft Access is a very powerful client/server development tool. One of the ways that you can retrieve data from a SQL Server is by using a pa…
Via a live example, show how to extract insert data into a SQL Server database table using the Import/Export option and Bulk Insert.
###### Suggested Courses
Course of the Month9 days, 18 hours left to enroll