Reputation: 339
I have a SQL Server 2005 table named Rentals
:
RentalID
Book
Date
I want to return, using a query, for each book, how many rentals were in each month for a given year.
The results should look something like this:
+--------------------------------+-----+-----+-----+
| Book | Jan | Feb | Mar |
+--------------------------------+-----+-----+-----+
| Isaac Asimov - Foundation | 2 | 5 | 3 |
| H.G. Wells - War of the Worlds | 4 | 3 | 1 |
| Frank Herbert - Dune | 7 | 4 | 6 |
+--------------------------------+-----+-----+-----+
My query so far:
SELECT
Book,
(SELECT COUNT(*) FROM Rentals WHERE month(Date)=1 AND year(Date)=2011),
(SELECT COUNT(*) FROM Rentals WHERE month(Date)=2 AND year(Date)=2011),
(SELECT COUNT(*) FROM Rentals WHERE month(Date)=3 AND year(Date)=2011),
(SELECT COUNT(*) FROM Rentals WHERE month(Date)=4 AND year(Date)=2011),
(SELECT COUNT(*) FROM Rentals WHERE month(Date)=5 AND year(Date)=2011),
(SELECT COUNT(*) FROM Rentals WHERE month(Date)=6 AND year(Date)=2011),
(SELECT COUNT(*) FROM Rentals WHERE month(Date)=7 AND year(Date)=2011),
(SELECT COUNT(*) FROM Rentals WHERE month(Date)=8 AND year(Date)=2011),
(SELECT COUNT(*) FROM Rentals WHERE month(Date)=9 AND year(Date)=2011),
(SELECT COUNT(*) FROM Rentals WHERE month(Date)=10 AND year(Date)=2011),
(SELECT COUNT(*) FROM Rentals WHERE month(Date)=11 AND year(Date)=2011),
(SELECT COUNT(*) FROM Rentals WHERE month(Date)=12 AND year(Date)=2011)
FROM Rentals
GROUP BY Book
Upvotes: 2
Views: 346
Reputation: 519
If you use pivot the code is much easier to maintain,
SELECT
BOOK,
[1] as Jan ,
[2] as Feb,
[3] as Mar,
[4] as Apr,
[5] as May,
[6] as Jun,
[7] as Jul,
[8] as Aug,
[9] as Sep,
[10] as Oct,
[11] as Nov,
[12] as Dec
FROM
(
SELECT
BOOK ,
DATEPART(MONTH,[DATE]) AS PER
FROM
Rentals
WHERE
DATEPART(YEAR,[DATE]) = 2014
) AS P PIVOT
(
COUNT(PER) FOR PER IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])
) AS DATA
Simple.
Upvotes: 0
Reputation: 247640
This can be written much simpler by using a CASE expression inside of an aggregate function. This process is called PIVOT:
select book,
sum(case when month(Date) = 1 then 1 else 0 end) Jan,
sum(case when month(Date) = 2 then 1 else 0 end) Feb,
sum(case when month(Date) = 3 then 1 else 0 end) Mar,
sum(case when month(Date) = 4 then 1 else 0 end) Apr,
sum(case when month(Date) = 5 then 1 else 0 end) May,
sum(case when month(Date) = 6 then 1 else 0 end) Jun,
sum(case when month(Date) = 7 then 1 else 0 end) Jul,
sum(case when month(Date) = 8 then 1 else 0 end) Aug,
sum(case when month(Date) = 9 then 1 else 0 end) Sep,
sum(case when month(Date) = 10 then 1 else 0 end) Oct,
sum(case when month(Date) = 11 then 1 else 0 end) Nov,
sum(case when month(Date) = 12 then 1 else 0 end) Dec
from Rentals
where year(date) = 2011
group by book;
See SQL Fiddle with Demo. Instead of querying the table multiple times for each column, you use conditional aggregation to get the count for each book during the month and year.
Upvotes: 3