views:

39

answers:

2

SQL Server 2008 again. I have a primary key pt_id and a datetime column order_dts for each id. I want to count the number of keys in each year from 1996-2008 and return eight results - a count for each year. For a single year

SELECT COUNT pm.pt_id AS '1996'
FROM dm.medications pm
WHERE (pm.order_dts BETWEEN '1/1/1996' and '12/31/1996')

works, but how I can I do all of the years without having to do something ridiculous like eight different queries?

Thank you!

+5  A: 
SELECT COUNT(*),  Year(pm.order_dts) as Year
FROM dm.medications pm
WHERE Year(pm.order_dts) between 1996 AND 2008
group by Year(pm.order_dts)

If you want it all in one row, you can do:

SELECT 
    sum(case when Year(pm.order_dts) = 1996 then 1 end) as Count1996,
    sum(case when Year(pm.order_dts) = 1997 then 1 end) as Count1997,
    sum(case when Year(pm.order_dts) = 1998 then 1 end) as Count1998,
    sum(case when Year(pm.order_dts) = 1999 then 1 end) as Count1999,
    sum(case when Year(pm.order_dts) = 2000 then 1 end) as Count2000,
    sum(case when Year(pm.order_dts) = 2001 then 1 end) as Count2001,
    sum(case when Year(pm.order_dts) = 2002 then 1 end) as Count2002,
    sum(case when Year(pm.order_dts) = 2003 then 1 end) as Count2003,
    sum(case when Year(pm.order_dts) = 2004 then 1 end) as Count2004,
    sum(case when Year(pm.order_dts) = 2005 then 1 end) as Count2005,
    sum(case when Year(pm.order_dts) = 2006 then 1 end) as Count2006,
    sum(case when Year(pm.order_dts) = 2007 then 1 end) as Count2007,
    sum(case when Year(pm.order_dts) = 2008 then 1 end) as Count2008
FROM dm.medications pm
RedFilter
@OrbMan: I have added the condition for limiting records as per year criteria.
shahkalpesh
I always forget about the YEAR function.
Joe
@shahkalpesh : Thanks!
RedFilter
I might change the WHERE clause to use strict dates so that the query can make use of any index on the date at least for filtering. I'm doing some testing on SQL 2008 right now to see if it's smart enough to use an index on the date when filtering by year and it looks like it may be. I just need to see if it's using the index because it's covering or because it knows that it can do direct comparisons. It looks like the latter though, so you might be able to leave the above as-is. Can anyone else confirm this?
Tom H.
Perfect! Thank you!
raoulcousins
After some more testing it looks like SQL 2008 does NOT properly use an index when you use the YEAR(date) = xxxx condition. :(You're better off with date >= xxxx-01-01 AND date < yyyy-01-01 where yyyy = xxxx + 1
Tom H.
A: 
select count(pm.pt_id) as count, datepart(yy, pm.order_dts) as year
from dm.medications pm
WHERE (pm.order_dts BETWEEN '1/1/1996' and '12/31/1996')
group by datepart(yy, pm.order_dts)
Joe