Reputation: 821
I need to run a query like this:
select SUM(TONS) as TONS
from MyView
where Date between '01.01.2017' and '12.31.2017'
group by DATEPART(MONTH, Date)
order by DATEPART(YEAR, Date) asc
The problem is if there is no data on 3rd month it returns 11 rows in total instead of 12. How can I replace missing dates with value of 0?
Upvotes: 0
Views: 41
Reputation: 4082
You can left join the result with months.
SELECT
C.M YourMonth,
COALESCE(Result.TONS, 0) AS TONS
FROM
(VALUES(1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12)) C(M) LEFT JOIN
(
SELECT
DATEPART(MONTH, T.Date) YourMonth,
SUM(T.TONS) AS TONS
FROM
MyView T
WHERE Date BETWEEN '01.01.2017' and '12.31.2017'
GROUP BY
DATEPART(MONTH, T.Date)
) Result ON C.M = Result.YourMonth
Upvotes: 1
Reputation: 38023
You could create a calendar table and join to that, or you can use an adhoc calendar like so:
declare @fromdate date = '20170101';
declare @thrudate date = '20171231';
;with n as (select n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(n))
, dates as (
select top (datediff(day, @fromdate,@thrudate)+1)
[Date]=convert(date,dateadd(day,row_number() over(order by (select 1))-1,@fromdate))
from n as deka cross join n as hecto cross join n as kilo
cross join n as tenK cross join n as hundredK
order by [Date]
)
, cal as (
select
[Date]
, [Month]=month([Date])
, [Year] =year([Date])
from dates
)
select
c.[Year]
, c.[Month]
, Tons = sum(v.Tons)
from cal c
left join MyView v
on c.[Date] = v.[Date]
where c.[Date] >= '20170101'
and c.[Date] <= '20171231'
group by c.[Year], c.[Month]
order by c.[Year], c.[Month]
calendar and numbers tables reference:
Upvotes: 3