Следующий скрипт представляет выходные данные в унифицированном виде: он показывает даты начала и окончания периода, а также общее количество за период.
Это также определило способы поиска значений для группировки по,По сути, вы можете видеть три различных шаблона: один для частоты 'day'
, другой для 'week'
и еще один для всех других типов частот.
Первый простейший: PeriodStart и PeriodEndпросто Date
.
В течение нескольких недель я использую довольно хорошо известный трюк, согласно которому первый день недели получается из заданной даты путем вычитания из нее значения, которое на единицу меньше его номера дня недели.,Конец недели определяется аналогично: мы просто добавляем 6
к тому же выражению.
Месяцы, кварталы и годы группируются следующим образом.Целое число соответствующих единиц между нулевой датой и данной датой добавляется обратно к нулевой дате.Это дает нам начало периода.Конец находится очень похоже, только мы добавляем число, которое на единицу больше, чем разница.Это дает начало следующего периода, поэтому мы затем вычитаем один день, что дает нам правильную дату окончания.
SELECT
PeriodStart,
PeriodEnd,
Count = SUM(Count)
FROM (
SELECT
PeriodStart = CASE @Frequency
WHEN 'day' THEN Date
WHEN 'week' THEN DATEADD(DAY, 1 - DATEPART(WEEKDAY, Date), Date)
WHEN 'month' THEN DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)
WHEN 'quarter' THEN DATEADD(QUARTER, DATEDIFF(QUARTER, 0, Date), 0)
WHEN 'year' THEN DATEADD(YEAR, DATEDIFF(YEAR, 0, Date), 0)
END,
PeriodEnd = CASE @Frequency
WHEN 'day' THEN Date
WHEN 'week' THEN DATEADD(DAY, 7 - DATEPART(WEEKDAY, Date), Date)
WHEN 'month' THEN DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, Date) + 1, 0))
WHEN 'quarter' THEN DATEADD(DAY, -1, DATEADD(QUARTER, DATEDIFF(QUARTER, 0, Date) + 1, 0))
WHEN 'year' THEN DATEADD(DAY, -1, DATEADD(YEAR, DATEDIFF(YEAR, 0, Date) + 1, 0))
END,
Count
FROM atable
WHERE Date BETWEEN @DateStart AND @DateEnd
) s
GROUP BY
PeriodStart,
PeriodEnd
EXEC spReport '1/1/2011', '12/31/2011', 'day'
:
PeriodStart PeriodEnd Count
----------- ---------- -----
2011-11-15 2011-11-15 6
2011-12-16 2011-12-16 9
2011-12-17 2011-12-17 2
2011-12-18 2011-12-18 5
EXEC spReport '1/1/2011', '12/31/2011', 'week'
:
PeriodStart PeriodEnd Count
----------- ---------- -----
2011-11-13 2011-11-19 6
2011-12-11 2011-12-17 11
2011-12-18 2011-12-24 5
EXEC spReport '1/1/2011', '12/31/2011', 'month'
:
PeriodStart PeriodEnd Count
----------- ---------- -----
2011-11-01 2011-11-30 6
2011-12-01 2011-12-31 16
EXEC spReport '1/1/2011', '12/31/2011', 'quarter'
:
PeriodStart PeriodEnd Count
----------- ---------- -----
2011-10-01 2011-12-31 22
EXEC spReport '1/1/2011', '12/31/2011', 'year'
:
PeriodStart PeriodEnd Count
----------- ---------- -----
2011-01-01 2011-12-31 22
Примечание: от MSDN :
Избегайте использования префикса sp_ при именовании процедур.Этот префикс используется SQL Server для обозначения системных процедур.Использование префикса может привести к сбою кода приложения, если существует системная процедура с таким же именем.Для получения дополнительной информации см. Разработка хранимых процедур (компонент Database Engine) .