SELECT DATEPART(month, orderdatetime), DATEPART(week, orderdatetime), DATEPART(day, orderdatetime), COUNT(*)
FROM #orders
GROUP BY
DATEPART(month, orderdatetime), DATEPART(week, orderdatetime), DATEPART(day, orderdatetime) WITH ROLLUP
Это сгруппирует COUNT
по дням, неделям и месяцам в одном запросе.
Недельные сводки будут иметь столбец NULL
в DATEPART(day, orderdatetime)
, месячные сводки будут иметь NULL
в столбцах DATEPART(day, orderdatetime)
и DATEPART(week, orderdatetime)
.
Чтобы сделать это для каждого часа, дня, недели или месяца из текущего без пробелов, используйте CTE
s:
WITH q_hours AS
(
SELECT 0 AS col_hour
UNION ALL
SELECT col_hour + 1
FROM q_hours
WHERE col_hour < 22
),
q_days AS
(
SELECT 0 AS col_day
UNION ALL
SELECT col_day + 1
FROM q_days
WHERE col_day < 31
),
q_months AS
(
SELECT 0 AS col_month
UNION ALL
SELECT col_month + 1
FROM q_months
WHERE col_month < 12
)
SELECT col_month, col_day, col_hour, COUNT(orderid)
FROM q_hours
CROSS JOIN
q_days
CROSS JOIN
q_months
LEFT JOIN
#orders
ON DATEDIFF(month, orderdatetime, GETDATE()) = col_month
AND DATEDIFF(day, orderdatetime, GETDATE()) % 31 = col_day
AND DATEDIFF(hour, orderdatetime, GETDATE()) % 24 = col_hour
GROUP BY
col_month, col_day, col_hour WITH ROLLUP
HAVING (
col_month = 0
AND col_day = 0
AND col_hour IS NOT NULL
) -- all hours within 24 hours from now
OR
(
col_month = 0
AND col_day <= 7
AND col_hour IS NULL
) -- all days within 7 days from now
OR
(
col_month <= 6
AND col_day IS NULL
AND col_hour IS NULL
) -- all months within 6 months from now