Я думаю, возможный источник проблем с использованием datepart(qq, ...
, поскольку другие ответы заключаются в том, что (1) это, похоже, не учитывает возможность установки даты, охватывающей несколько лет, и (2) она делает предположения о самой ранней дате в вашем наборе данных , Я попытался написать решение, которое будет работать для любой даты начала, даже если это не первый день месяца. Это немного сложнее, поэтому, возможно, кто-то может предложить способ упростить его.
-- Sample data from the question.
declare @hits table (hitdate date, originid bigint, hitcount int);
insert @hits values
(convert(date, '20110501', 112), 2, 25),
(convert(date, '20110501', 112), 3, 3),
(convert(date, '20110604', 112), 2, 1),
(convert(date, '20110604', 112), 6, 11),
(convert(date, '20110605', 112), 7, 9),
(convert(date, '20110905', 112), 2, 25),
(convert(date, '20111007', 112), 3, 3),
(convert(date, '20111117', 112), 2, 1),
(convert(date, '20111201', 112), 6, 11),
(convert(date, '20120601', 112), 7, 9);
-- Define the date range that we're concerned with.
declare @beginDate date, @endDate date;
select
@beginDate = min(hitdate),
@endDate = convert(date, getdate())
from
@hits;
-- Build a list of three-month periods that encompass the date range defined
-- above. Each period will be inclusive on the lower end of the range and
-- exclusive on the upper end.
declare @Trimester table (beginDate date, endDate date);
while @beginDate <= @endDate
begin
insert @Trimester values (@beginDate, dateadd(m, 3, @beginDate));
set @beginDate = dateadd(m, 3, @beginDate);
end;
-- Finally, assign each hit to one of these periods.
select
[Trimester] =
convert(varchar, T.beginDate) +
' to ' +
convert(varchar, dateadd(d, -1, T.endDate)),
H.originid,
hitcount = sum(H.hitcount)
from
@hits H
inner join @Trimester T on
H.hitdate >= T.beginDate and
H.hitdate < T.endDate
group by
T.beginDate,
T.endDate,
H.originid
order by
T.beginDate,
H.originid;
Результирующий набор:
Одно различие между моим результатом установить и у вас, что ваша содержит запись о том, что были нулевые хиты для originid = 1
. Я ничего не сделал с этим, так как я не знаю, где вы храните набор допустимых значений originid
, но вам должно быть довольно легко настроить этот запрос, чтобы поддержать это, если хотите, просто вмешавшись в присоединяется к заключительному этапу.
Update: Чуть больше моих проблем с использованием datepart
:
Использование datepart(qq, hitdate)
само по себе предполагает, что границы квартала календарные кварталы, например, 1 апреля-30 июня, как уже было отмечено в другом ответе.
С помощью чего-то вроде datepart(qq, dateadd(mm,1,hitdate))
сдвигает квартал на месяц, поэтому вы начинаете 1 мая, как в ваших данных образца, но предположите, что хотите начать в июне, а не в мае. Вы должны изменить запрос.
datepart(qq, ...
само по себе будет возвращать то же значение для двух дат, которые находятся в том же квартале, но в разные годы. Таким образом, хиты 1 мая 2011 года и 1 мая 2012 года будут сгруппированы вместе. Вы можете приспособиться к этому, но на момент написания этой статьи другие ответы не поступают.
Использование datepart
любым из способов, описанных выше, предполагает, что кварталы начинаются в первый день месяца. Предположим, что самая ранняя дата в вашем результирующем наборе была 15 мая. Мой запрос будет обрабатываться 15 мая-14 августа как первый квартал, 15 августа-14 ноября, как второй квартал и т. Д.
Это последнее, я думаю, может быть наиболее трудно преодолеть, если вы хотите, решение, которое использует datepart(qq, ...)
. Если вам будет удобно предположить, что дата начала - это первый день месяца, то возможно более простое решение, чем я предложил.
В запросе выше, если вы хотите использовать другую дату начала, вы просто назначаете дату, которую вы хотите, @beginDate
.
Важнейшая часть отсутствует. Вы хотите слить годы? –