Reputation: 578
I have 2 tables Payments and Customers.
We have 5 types of customer 1,2,3,4,5.
I want to get total payments by customer type (1,2,3,4,5) in each month of given year.
And if any customer type not have any payment than it should be 0.
Below is my current query :-
SELECT
"Month" = month(o.PaymentDate)
, "Year" = year(o.PaymentDate)
, Amount = sum(o.Amount)
, c.CustomerTypeID
FROM
Payments o
INNER JOIN
Customers c ON o.CustomerID = c.CustomerID
WHERE
o.PaymentDate >= convert(DATETIME, '1/1/2013 12:00:00 AM')
AND o.PaymentDate < convert(DATETIME, '12/31/2013 12:00:00 AM')
GROUP BY
month(o.PaymentDate)
, year(o.PaymentDate)
,c.CustomerTypeID
ORDER BY
year(o.PaymentDate)
, month(o.PaymentDate)
,c.CustomerTypeID
And Result is :-
Month Year Amout CustomerTypeID 1 2013 456 1 1 2013 678 2 1 2013 346 3 1 2013 3245 5
As currently it is not giving data for CustomerType 4, so I want to show 0 in amount column and month and Year will be same.
Can any body help me.
Thanks in advance.
Upvotes: 0
Views: 3481
Reputation: 51494
SELECT
2013 as year,
months.monthno,
Amount = isnull(sum(o.Amount),0),
c.CustomerTypeID
FROM
customers c
cross join
(select number monthNo from master..spt_values where type='p' and number between 1 and 12) months
left join payments o
ON o.CustomerID = c.CustomerID
AND year(o.PaymentDate)=2013
AND month(o.PaymentDate) = months.monthNo
GROUP BY
months.monthno, c.CustomerTypeID
ORDER BY
months.monthno, c.CustomerTypeID
Upvotes: 1
Reputation: 6999
When you use WHERE
with aggregation you should seriously consider using GROUP BY ALL
and not GROUP BY
:
From - MS Technet:
If you use ALL, the query results include all groups produced by the GROUP BY clause, even if some of the groups have no rows that meet the search conditions. Without ALL, a SELECT statement that includes GROUP BY does not show groups for which no rows qualify.
SELECT
"Month" = month(o.PaymentDate)
, "Year" = year(o.PaymentDate)
, Amount = sum(o.Amount)
, c.CustomerTypeID
FROM
Payments o
INNER JOIN
Customers c ON o.CustomerID = c.CustomerID
WHERE
o.PaymentDate >= convert(DATETIME, '1/1/2013 12:00:00 AM')
AND o.PaymentDate < convert(DATETIME, '12/31/2013 12:00:00 AM')
GROUP BY ALL
month(o.PaymentDate)
, year(o.PaymentDate)
,c.CustomerTypeID
ORDER BY
year(o.PaymentDate)
, month(o.PaymentDate)
,c.CustomerTypeID
Upvotes: 0
Reputation: 3108
Use Right outer join to have all customers and Coalesce(amount,0) for returning 0 instead of null.
SELECT
c.CustomerTypeID
FROM
(SELECT "Month" = month(o.PaymentDate)
, "Year" = year(o.PaymentDate)
, Amount = sum(o.Amount)
, o.CustomerID
FROM Payments o
WHERE
o.PaymentDate >= convert(DATETIME, '1/1/2013 12:00:00 AM')
AND o.PaymentDate < convert(DATETIME, '12/31/2013 12:00:00 AM')
) D
RIGHT OUTER JOIN
Customers c ON o.CustomerID = c.CustomerID
GROUP BY
D.MONTH
, D.YEAR
,c.CustomerTypeID
ORDER BY
D.MONTH
, D.YEAR
,c.CustomerTypeID
Upvotes: 0