SELECT DATEPART(month, orderdatetime), DATEPART(week, orderdatetime), DATEPART(day, orderdatetime), COUNT(*)
FROM
GROUP BY
DATEPART(month, orderdatetime), DATEPART(week, orderdatetime), DATEPART(day, orderdatetime) WITH ROLLUP
This will group COUNTby day, week and month in one request.
Weekly swaps will have a column NULLin the column DATEPART(day, orderdatetime), in the accumulators of the month will be NULLin the columns DATEPART(day, orderdatetime)and DATEPART(week, orderdatetime).
To do this for every hour, day, week or month from the current one without spaces, use 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
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
)
OR
(
col_month = 0
AND col_day <= 7
AND col_hour IS NULL
)
OR
(
col_month <= 6
AND col_day IS NULL
AND col_hour IS NULL
)