Я думаю, у меня есть решение здесь. Есть 3 основных шага:
- Получить дату в каждом из 12 месяцев
- Проверьте, находится ли эта дата между начальной и конечной датой
- PIVOT результат
Чтобы получить 12 дат, по одной на каждый месяц, я использовал небольшую рекурсивную инструкцию типа WITH для создания временной таблицы с 1 столбцом из 12 дат:
WITH months (date) AS (
SELECT GETDATE() AS date
UNION ALL
SELECT
DATEADD(MONTH,1,date)
FROM months
WHERE DATEDIFF(MONTH,GETDATE(),date) < 12)
Отсюда я могу ПЕРЕКРЕСТИТЬ эту временную таблицу с таблицей с информацией, которая мне действительно нужна. Затем я использую ГДЕ дату между началом и концом, чтобы отфильтровать записи, не относящиеся к этому месяцу. Вот как то так:
SELECT other.Title, MONTH(months.date) CROSS JOIN other
WHERE months.date BETWEEN other.start AND other.end
На этом шаге мы должны быть осторожны, чтобы ВЫБРАТЬ только те столбцы, которые мы хотим получить в результате, или те, которые будут агрегированы с помощью оператора PIVOT.
Наконец, мы должны повернуть результат:
PIVOT (MAX(PID) FOR date IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12]))
Таким образом, результирующий запрос может выглядеть примерно так:
WITH months (date) AS (
SELECT GETDATE() AS date
UNION ALL
SELECT
DATEADD(MONTH,1,date)
FROM months
WHERE DATEDIFF(MONTH,GETDATE(),date) < 12)
SELECT Title,
[1] AS January,
[2] AS February,
[3] AS March,
[4] AS April,
[5] AS May,
[6] AS June,
[7] AS July,
[8] AS August,
[9] AS September,
[10] AS October,
[11] AS November,
[12] AS December
FROM
(
SELECT other.Title,MONTH(months.date)
CROSS JOIN other
WHERE months.date BETWEEN other.startDate AND other.endDate
) AS subquery
PIVOT (MAX(PID) FOR date IN
([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])) AS p
Я избавился от всех других сложностей, через которые прошел, чтобы объединить другую информацию, которая мне была нужна, так что на самом деле это не тот запрос, который я написал, но он должен включать базовую структуру запроса, которую я использовал для получения результата как мне было нужно.