I’m trying to write a SQL query that produces a table with summarized values for each year and month.
I have a table that looks something like this:
TABLENAME: TIME id cID cDate cTime 1 254 2019-10-11 5 2 259 2019-10-13 4 3 268 2020-01-17 6 4 268 2020-01-18 9 5 271 2020-01-21 4 6 267 2020-02-19 8
And another table that looks like this:
TABLENAME: CASE id name invoice status 254 Acme Yes finish 259 Tex NoFakt finish 268 Rex C Yes *Null* 267 Hydro *Null* open 271 Corp Yes finish
I want to have a query that returns the sum for each month like this:
Year Month RegTime Invoiced ToBeInvoiced 2019 10 5 5 0 2019 11 0 0 0 2019 12 0 0 0 2020 1 19 4 15 2020 2 8 0 8
Explanation of the output:
Year and Month are obvious
RegTime should be the sum of all TIME.cTime WHERE CASE.invoice <> ‘NoFakt’
Invoiced should be the sum of all TIME.cTIME WHERE CASE.invoice = ‘Yes’ AND CASE.status = ‘finish’
ToBeInvoiced should be the sum of all TIME.cTIME WHERE CASE.invoice = ‘Yes’ AND CASE.status <> ‘finish’
I have tried this query, but with this i need to loop a predefined year and month value in my programming code instead of simply having a sql statement that are doing all the work. ThereĀ“s got to be a simpler way than this…
select (select sum(cTIME) from TIME inner join CASE on TIME.cID = CASE.id WHERE CASE.invoice <> 'NoFakt' AND DATEPART(yy, cDate) = '2019' AND DATEPART(mm, cDate) = '10') AS RegTime, (select sum(cTIME) from TIME inner join CASE on TIME.cID = CASE.id WHERE CASE.invoice = 'Yes' AND CASE.status = 'finish' AND DATEPART(yy, cDate) = '2019' AND DATEPART(mm, cDate) = '10') AS Invoiced, (select sum(cTIME) from TIME inner join CASE on TIME.cID = CASE.id WHERE CASE.invoice = 'Yes' AND CASE.status <> 'finish' AND DATEPART(yy, cDate) = '2019' AND DATEPART(mm, cDate) = '10') AS ToBeInvoiced
Advertisement
Answer
Use conditional
aggregation :
SELECT YEAR(T.cDate) AS YR, MONTH(T.cDate) AS Mnth, SUM(CASE WHEN C.invoice <> 'NoFakt' THEN C.cTIME ELSE 0 END) AS RegTime, SUM(CASE WHEN C.invoice = 'Yes' AND C.status = 'finish' THEN C.cTIME ELSE 0 END) AS Invoiced, SUM(CASE WHEN C.invoice = 'Yes' AND C.status <> 'finish' THEN C.cTIME ELSE 0 END) AS ToBeInvoiced FROM TIME T INNER JOIN CASE C ON T.cID = C.id GROUP BY YEAR(T.cDate), MONTH(T.cDate);
Note: Do not use reserved
keyword as Object Name.