【发布时间】:2018-07-02 00:52:31
【问题描述】:
我需要编写一个查询来获取:
日期结果集。结果集包含从当前日期前 3 个月开始的所有日期 + 当前日期后 12 个月(包括当前月份)的所有日期。例如:说当前日期:7/25/2018 结果集应包含从 2018 年 4 月 1 日到 2019 年 6 月 30 日的所有日期
从此结果集中,将获得每个月的倒数第二个工作日。
条件:倒数第二个工作日应为平日和非节假日。假期列表包含在名为RT_STATEHOLIDAY_MV 的表中。
RT_STATEHOLIDAY_MV:
Description
-----------
01/02/17
01/16/17
02/28/17
04/27/18
05/29/17
07/04/17
09/04/17
11/10/17
11/23/17
12/25/17
到目前为止我所尝试的:
WITH cte AS
(
SELECT
1 AS DayID,
DATEADD(month, -3, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0)) AS FromDate,
DATENAME(dw, DATEADD(month, -3, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0))) AS Dayname
UNION ALL
SELECT
cte.DayID + 1 AS DayID,
DATEADD(d, 1, cte.FromDate),
DATENAME(dw, DATEADD(d, 1, cte.FromDate)) AS Dayname
FROM
cte
WHERE
DATEADD(d, 1, cte.FromDate) < DATEADD(month, 12, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0))
) ,
wrkInd as
(
SELECT
(SELECT CONVERT(VARCHAR(10), CTE.FromDate, 1) AS [MMDDYY]) AS Date,
CASE
WHEN REFSH.DESCRIPTION IS NULL THEN 'Y' ELSE 'N' END AS WORKDAY_INDICATOR
FROM
CTE
LEFT JOIN
RT_STATEHOLIDAY_MV REFSH ON CTE.FromDate = REFSH.DESCRIPTION
WHERE
DayName NOT IN ('Saturday','Sunday')
),
secLastWrkDay AS
(
SELECT
*,
CASE WHEN wrkInd.Date =
--(SELECT MAX(wrkInd.Date)
--from wrkInd where wrkInd.Date <=
(select case
datename(WEEKDAY,EOMONTH(wrkInd.Date))
when 'Saturday' then convert(datetime,(EOMONTH(wrkInd.Date)))-2
when 'Sunday' then convert(datetime, (EOMONTH(wrkInd.Date)))-3
when 'Monday' then convert(datetime, (EOMONTH(wrkInd.Date)))-3
else convert(datetime,EOMONTH(wrkInd.Date))-1
end)
-- AND wrkInd.WORKDAY_INDICATOR='Y'
-- AND MONTH(tab)=MONTH(wrkInd.Date)
--)
THEN 'Y' ELSE 'N' END AS SECOND_LAST_WRK_DAY
FROM wrkInd
),
cutoff AS
(
SELECT
secLastWrkDay.Date, secLastWrkDay.WORKDAY_INDICATOR,
CASE
WHEN MONTH(secLastWrkDay.Date) = MONTH(EOMONTH(secLastWrkDay.Date))
AND YEAR(secLastWrkDay.Date) = YEAR(EOMONTH(secLastWrkDay.Date))
AND secLastWrkDay.WORKDAY_INDICATOR = 'Y'
AND secLastWrkDay.SECOND_LAST_WRK_DAY = 'Y'
THEN 'Y'
ELSE 'N'
END AS SECOND_LAST_WORK_DAY
FROM
secLastWrkDay
)
SELECT *
FROM cutoff
OPTION (MaxRecursion 700);
这可行,但这并没有考虑假期表中的假期。
【问题讨论】:
-
关于日历、节假日、工作日和非工作日的讨论一直在发生。只需在互联网上搜索有关使用所需信息创建真实日历表的建议(并注意您对工作日的假设 - 自然和非自然灾害无处不在)。并吸取过去的教训。没有人 - NO ONE - 应该使用 2 位数年份的日期。
标签: sql-server