У меня есть один или несколько начальных и конечных периодов, которые могут быть последовательными, перекрывающимися или между ними. Моя цель - показать все 12 месяцев независимо от того, когда начинается период; то есть я могу видеть месяцы до периода, в течение периода и, возможно, после периода. Для этого примера я проверяю его по 2019 году, поэтому я хочу, чтобы все 12 месяцев были заполнены для 2019.
У меня есть следующие примеры данных, чтобы проиллюстрировать проблему:
DECLARE @DATES TABLE (ID int, EffectiveDate date, EffectiveEndDate date)
INSERT INTO @DATES
VALUES
(43, '2018-10-01', '2019-09-30'),
(43, '2019-10-01', '2020-09-30'),
(44, '2019-10-01', '2020-09-30');
У меня также есть таблица подсчета, которая имеет все 12 месяцев и начало месяца (для краткости опущена, но это временная таблица со столбцом с именем N
, который имеет значение 1-12, представляющее месяц, и столбец StartOfMonth
, который является начальной датой месяца. Теперь мне нужно, чтобы каждый идентификатор (в данном случае 43 и 44) показывал все 12 месяцев. Это легко с 43, где есть две записи, которые запускаются с октября С 2018 по ноябрь 2020 года, поскольку он выпадает на все 12 месяцев. 44 однако дает мне только октябрь, ноябрь и декабрь, поскольку в октябре начинается только одна строка. Я не могу добавить строку за предыдущие месяцы.
Таблица месяцев просто определяется следующим образом:
DROP TABLE IF EXISTS #Months;
CREATE TABLE #Months (N tinyint, StartOfMonth date);
INSERT INTO #Months
VALUES
(1, DATEFROMPARTS(2019, 1, 1)),
(2, DATEFROMPARTS(2019, 2, 1)),
(3, DATEFROMPARTS(2019, 3, 1)),
(4, DATEFROMPARTS(2019, 4, 1)),
(5, DATEFROMPARTS(2019, 5, 1)),
(6, DATEFROMPARTS(2019, 6, 1)),
(7, DATEFROMPARTS(2019, 7, 1)),
(8, DATEFROMPARTS(2019, 8, 1)),
(9, DATEFROMPARTS(2019, 9, 1)),
(10, DATEFROMPARTS(2019, 10, 1)),
(11, DATEFROMPARTS(2019, 11, 1)),
(12, DATEFROMPARTS(2019, 12, 1));
Код:
SELECT Month = m.N,
d.ID,
d.EffectiveDate,
d.EffectiveEndDate,
-- This flag doesn't mean anything, just so I can better see the results I'm getting
Ind = CASE
WHEN m.StartOfMonth BETWEEN d.EffectiveDate AND d.EffectiveEndDate
THEN 1
ELSE 0
END
FROM @dates d
LEFT JOIN #Months m
ON m.N BETWEEN 1 AND 12
WHERE
m.StartOfMonth
BETWEEN EffectiveDate AND EffectiveEndDate
ORDER BY ID, m.N;
Это дает мне следующий (неправильный) вывод:
Month ID EffectiveDate EffectiveEndDate Ind
1 43 2018-10-01 2019-09-30 1
2 43 2018-10-01 2019-09-30 1
3 43 2018-10-01 2019-09-30 1
4 43 2018-10-01 2019-09-30 1
5 43 2018-10-01 2019-09-30 1
6 43 2018-10-01 2019-09-30 1
7 43 2018-10-01 2019-09-30 1
8 43 2018-10-01 2019-09-30 1
9 43 2018-10-01 2019-09-30 1
10 43 2019-10-01 2020-09-30 1
11 43 2019-10-01 2020-09-30 1
12 43 2019-10-01 2020-09-30 1
!!! THIS PART IS WRONG !!!
10 44 2019-10-01 2020-09-30 1
11 44 2019-10-01 2020-09-30 1
12 44 2019-10-01 2020-09-30 1
Если Я пропускаю е Эффективная дата / эффективная дата окончания проверки или попытка сделать какое-то заявление о ситуации, где я говорю, что если месяц начинается до даты вступления в силу, тогда включите его в любом случае 43 удваивается на месяцы, потому что есть две строки, а 44 работает, как ожидалось.
Мне нужно получить это:
Month ID EffectiveDate EffectiveEndDate Ind
1 43 2018-10-01 2019-09-30 1
2 43 2018-10-01 2019-09-30 1
3 43 2018-10-01 2019-09-30 1
4 43 2018-10-01 2019-09-30 1
5 43 2018-10-01 2019-09-30 1
6 43 2018-10-01 2019-09-30 1
7 43 2018-10-01 2019-09-30 1
8 43 2018-10-01 2019-09-30 1
9 43 2018-10-01 2019-09-30 1
10 43 2019-10-01 2020-09-30 1
11 43 2019-10-01 2020-09-30 1
12 43 2019-10-01 2020-09-30 1
1 44 2019-10-01 2020-09-30 0
2 44 2019-10-01 2020-09-30 0
3 44 2019-10-01 2020-09-30 0
4 44 2019-10-01 2020-09-30 0
5 44 2019-10-01 2020-09-30 0
6 44 2019-10-01 2020-09-30 0
7 44 2019-10-01 2020-09-30 0
8 44 2019-10-01 2020-09-30 0
9 44 2019-10-01 2020-09-30 0
10 44 2019-10-01 2020-09-30 1
11 44 2019-10-01 2020-09-30 1
12 44 2019-10-01 2020-09-30 1
, где все 12 месяцев отображаются для всех ситуаций, будь то последовательные диапазоны или один диапазон, начинающийся в любой заданной точке года.