#sql #sql-server #case #exists
#sql #sql-сервер #кейс #существует
Вопрос:
У меня есть таблица, содержащая записи с датами начала и окончания, поэтому я должен захватить каждую запись, которая началась в пятницу, и если какая-либо пятница является праздничной, получить четверг, и если пятница и четверг являются праздничными днями, получить среду и так далее…
В настоящее время у меня есть две таблицы TableA
для записей и Calendar
для получения праздников.
Мой TableA
выглядит следующим образом:
id beg end
--------------------------
1 11/01/2019 14/01/2019
2 10/01/2019 14/01/2019
3 09/01/2019 15/01/2019
...
Календарь выглядит следующим образом:
iddate date weekday isholiday
---------------------------------------
20190109 09/01/2019 3 0 --0=False / 1=True
20190110 10/01/2019 4 0
20190111 11/01/2019 5 1
...
Для обеих таблиц я использую WHERE EXISTS
для получения пятниц и условия праздника, которое фактически отображает результаты:
SELECT *
FROM TableA t
WHERE EXISTS (SELECT 1
FROM dbo.Calendar AS c
WHERE c.date = CAST(t.BEG AS DATETIME)
AND c.weekday = CASE
WHEN (C.weekday = 5 AND C.isholiday = 0)
THEN 5 --keep friday
--WHEN ((C.weekday= 4 AND C.isholiday= 1) OR (C.weekday= 5 AND C.isholiday= 1)) THEN 3 --keep wednesday / not working
ELSE 4 --keep thursday
END
AND DATEPART(yyyy, T.beg) = 2019)
ORDER BY
CAST(INI AS [datetime])
Если пятница — выходной день, на нем будет отображаться это:
id beg end
--------------------------
2 10/01/2019 14/01/2019
3 09/01/2019 15/01/2019
Если пятница и четверг являются праздничными днями, в нем должно отображаться:
id beg end
--------------------------
3 09/01/2019 15/01/2019
Масштабирование с помощью этого WHEN ((C.weekday= 4 AND C.isholiday= 1) OR (C.weekday= 5 AND C.isholiday= 1))
просто прерывает весь запрос, и я получаю -почти- случайные даты. Есть какой-нибудь способ увеличить его, не слишком расширяя запрос?
Комментарии:
1. Заполнена ли ваша таблица календаря в том смысле, что в ней 365 строк за 2019 год? Кроме того, ваши ожидаемые результаты не соответствуют вашему первоначальному описанию — раздел с надписью «Если пятница была праздничной» включает событие из среды, хотя четверг не является праздничным днем, не могли бы вы, пожалуйста, уточнить? Наконец, на какой версии SQL Server вы работаете?
2. @Brian Да, в нем хранятся данные за 30 лет. Я имею в виду, что мне нужна каждая строка с последнего рабочего дня для каждой недели, поэтому, если в таблице календаря пятница, это праздник, последний рабочий день будет в четверг, и я на SQL Server 2008. Спасибо!
Ответ №1:
Основываясь на вашем комментарии, я бы использовал общее табличное выражение:
;With cte_Last_Day_Of_Week
As
(
Select
c.iddate
, c.date
, Row_Number() Over (Partition By DatePart(Week, c.date) Order By c.date Desc) As RN
From dbo.Calendar As c
Where c.isholiday = 0
)
Row_Number()
Будет отмечаться дата последнего непраздничного дня каждой недели со значением 1
. Затем вы можете объединить их с этим, как с таблицей.
Дайте мне знать, имеет ли это смысл.