我需要一个sql函数,除星期六星期日和公众假期外,必须返回第5个上一个营业日期,
例如:我应该在星期四(04-01-2018)获得,如果我之间没有任何公共假期可以实现,
SELECT DATEADD(DAY, CASE DATENAME(WEEKDAY, GETDATE())
WHEN 'Sunday' THEN -2
WHEN 'Monday' THEN -3
ELSE -1 END, DATEDIFF(DAY, 5, GETDATE()))
但如何省略公众假期, 任何人都可以帮助我
答案 0 :(得分:2)
如果你不想(或者你不能)创建一个日历" tally" table(包含标识假日和周末日的列)您可以尝试查询,如下一个。
假期表的样本数据
CREATE TABLE HOL_TAB (DAT DATETIME);
INSERT INTO HOL_TAB VALUES ('2018-01-05');
INSERT INTO HOL_TAB VALUES ('2018-01-04');
查询使用CTE来"创建"在飞行中一个小的计数日历表(我使用12作为限制,但你可以改变它。)
最后SELECT
使用带假日表的联接来排除那些日子,然后ROW_NUMBER()
提取"首先"五天。
要保持查询类似于我使用的DATENAME
,但我建议避免使用它,而是使用其他方法。
WITH CAL_TAB AS (
SELECT DATEADD(dd, 0, CAST(GETDATE() AS DATE) ) AS DAT
, 1 AS COUN
UNION ALL
SELECT DATEADD(dd, -1- CASE DATENAME (WEEKDAY, DATEADD(dd,-1,B.DAT) ) WHEN 'Sunday' THEN 2 WHEN 'Saturday' THEN 1 ELSE 0 END, B.DAT ) AS DAT
, B.COUN+1 AS COUN
FROM CAL_TAB B
WHERE B.COUN<12 /* 12 is just to limit number of days */
)
SELECT DAT, WD
FROM (SELECT C.DAT, C.COUN, DATENAME(WEEKDAY, C.DAT) AS WD, ROW_NUMBER() OVER (ORDER BY COUN) AS RN
FROM CAL_TAB C
WHERE NOT EXISTS(SELECT DAT FROM HOL_TAB D WHERE D.DAT=C.DAT)
) E WHERE RN<=5;
输出:
DAT WD
1 10.01.2018 00:00:00 Wednesday
2 09.01.2018 00:00:00 Tuesday
3 08.01.2018 00:00:00 Monday
4 03.01.2018 00:00:00 Wednesday
5 02.01.2018 00:00:00 Tuesday
答案 1 :(得分:0)
尝试此逻辑
WITH CTE
AS
(
SELECT
MyDate = DATEADD(DD,-5,GETDATE())
)
SELECT
MyDate = CASE WHEN DATENAME(WEEKDAY, MyDate) IN ('Sunday','Saturday')
THEN NULL
WHEN MHL.Holiday IS NOT NULL
THEN NULL
ELSE CTE.MyDate END
FROM CTE
LEFT JOIN MyHoliDayList MHL
ON CTE.MyDate = MHL.Holiday
答案 2 :(得分:0)
尝试此方法:
DECLARE @Holiday TABLE(HoliDay DATE)
INSERT INTO @Holiday VALUES ('2018-01-02')
INSERT INTO @Holiday VALUES ('2018-01-05')
DECLARE @WithOutHoliDay DATETIME = (SELECT DATEADD(DAY, CASE DATENAME(WEEKDAY, GETDATE())
WHEN 'Sunday' THEN -2
WHEN 'Monday' THEN -3
ELSE -1 END, DATEDIFF(DAY, 5, GETDATE())))
SELECT DATEADD(DAY,0-
(SELECT COUNT(1)
FROM @Holiday
WHERE HoliDay BETWEEN @WithOutHoliDay AND GETDATE()),@WithOutHoliDay)
这应该给出,你究竟需要什么...