declare @baseDate datetime
set @baseDate = '1 May 2005'
SELECT
datediff(year, @baseDate, [date]) AS YearBucket
,COUNT(*) AS cnt
FROM logins
GROUP BY datediff(year, @baseDate, [date])
ORDER BY datediff(year, @baseDate, [date])
РЕДАКТИРОВАТЬ - извинения, вы правы. Вот исправленная версия (я должен был использовать тестовую таблицу, чтобы начать с ...)
create table logins (date datetime, foo int)
insert logins values ('1 may 2005', 1)
insert logins values ('1 apr 2006', 2)
insert logins values ('1 may 2006', 3)
declare @baseDate datetime
set @baseDate = '1 May 2005'
SELECT
datediff(day, @baseDate, [date]) / 365 AS YearBucket
,COUNT(*) AS cnt
FROM logins
GROUP BY datediff(day, @baseDate, [date]) / 365
ORDER BY datediff(day, @baseDate, [date]) / 365
Измените единицы измерения даты, если вы хотите больше детализации, чем дни.
РЕДАКТИРОВАТЬ # 2 - хорошо, вот более надежное решение, которое обрабатывает високосные годы :)
РЕДАКТИРОВАТЬ № 3 - На самом деле это не обрабатывает високосные годы, вместо этого он позволяет указывать переменные интервалы времени Используйте безопасный метод високосного года с dateadd (year, 1, @baseDate).
declare @baseDate datetime, @interval datetime
--@interval is expressed as time above 0 time (1/1/1900)
select @baseDate = '1 May 2005', @interval = '1901'
declare @timeRanges table (beginIntervalInclusive datetime, endIntervalExclusive datetime)
declare @i int
set @i = 1
while @i <= 10
begin
insert @timeRanges values(@baseDate, @baseDate + @interval)
set @baseDate = @baseDate + @interval
set @i = @i + 1
end
SELECT
tr.beginIntervalInclusive,
tr.endIntervalExclusive,
COUNT(*) AS cnt
FROM logins join @timeRanges as tr
on logins.date >= tr.beginIntervalInclusive
and logins.date < tr.endIntervalExclusive
GROUP BY tr.beginIntervalInclusive, tr.endIntervalExclusive
ORDER BY tr.beginIntervalInclusive