Я изменил OMG Ponies 'ответ, потому что он выглядел как хорошая идея, он просто имел неправильное значение week_end
для каждой недели и также показывал будущие недели вместо прошлых недель. Я придумал следующее:
WITH dates AS (
SELECT DATEADD(
DD,
1 - DATEPART(DW, CONVERT(VARCHAR(10), starting_date, 111)),
CONVERT(VARCHAR(10), starting_date, 111)
) AS midnight
FROM (
SELECT DATEADD(WEEK, -3, GETDATE()) AS starting_date
) AS starting_date_view
UNION ALL
SELECT DATEADD(DD, 7, midnight)
FROM dates
WHERE DATEADD(DD, 7, midnight) < GETDATE()
) SELECT midnight AS week_start,
DATEADD(SS, -1, DATEADD(DAY, 7, midnight)) AS week_end
FROM dates
Генерирует последние 4 недели:
week_start week_end
2010-02-14 00:00:00.000 2010-02-20 23:59:59.000
2010-02-21 00:00:00.000 2010-02-27 23:59:59.000
2010-02-28 00:00:00.000 2010-03-06 23:59:59.000
2010-03-07 00:00:00.000 2010-03-13 23:59:59.000
Это лучше, чем мой предыдущий ответ , я думаю, потому что он не основан на другой таблице, имеющей определенное количество строк. Количество сгенерированных недель можно изменить, изменив только одну цифру: 3 в SELECT DATEADD(WEEK, -3, GETDATE()) AS starting_date
. Текущая неделя включена, и эта цифра показывает, сколько дополнительных недель до текущей недели должно быть показано.
Перебирать прошлые недели до настоящего времени, исключая текущую неделю
Обновление: , и вот версия, исключающая текущую неделю:
WITH dates AS (
SELECT DATEADD(
DD,
1 - DATEPART(DW, CONVERT(VARCHAR(10), starting_date, 111)),
CONVERT(VARCHAR(10), starting_date, 111)
) AS midnight_sunday
FROM (
SELECT DATEADD(WEEK, -4, GETDATE()) AS starting_date
) AS starting_date_view
UNION ALL
SELECT DATEADD(DD, 7, midnight_sunday)
FROM dates
WHERE DATEADD(DD, 7, midnight_sunday) <
DATEADD(
DD,
1 - DATEPART(DW, CONVERT(VARCHAR(10), GETDATE(), 111)),
CONVERT(VARCHAR(10), GETDATE(), 111)
)
) SELECT midnight_sunday AS week_start,
DATEADD(SS, -1, DATEADD(DAY, 7, midnight_sunday)) AS week_end
FROM dates
Результаты:
week_start week_end
2010-02-07 00:00:00.000 2010-02-13 23:59:59.000
2010-02-14 00:00:00.000 2010-02-20 23:59:59.000
2010-02-21 00:00:00.000 2010-02-27 23:59:59.000
2010-02-28 00:00:00.000 2010-03-06 23:59:59.000
Итерация за прошедшие месяцы до настоящего момента
Позже я обнаружил необходимость ежемесячной версии этого запроса. Вот эта модификация:
WITH dates AS (
SELECT CAST(
FLOOR(CAST(starting_date AS DECIMAL(12, 5))) -
(DAY(starting_date) - 1) AS DATETIME
) AS month_start
FROM (
SELECT DATEADD(MONTH, -3, GETDATE()) AS starting_date
) AS starting_date_view
UNION ALL
SELECT DATEADD(MONTH, 1, month_start)
FROM dates
WHERE DATEADD(MONTH, 1, month_start) < GETDATE()
) SELECT month_start,
DATEADD(SS, -1, DATEADD(MONTH, 1, month_start)) AS month_end
FROM dates
ORDER BY month_start DESC