填写工作日表的最简单方法

时间:2016-03-01 14:48:06

标签: sql sql-server date

我有一个表working_days,其中一列date的日期类型为

我需要在美国填写工作日。

你能建议我这样做吗?

手动太长了。

3 个答案:

答案 0 :(得分:3)

您可以使用递归CTE来完成此任务。这只排除了周末。使用DATEFIRST,你可以弄清楚周末是哪一天。无论一周中的哪一天设置为DATEFIRST,此查询都应该有效。

;WITH DatesCTE
 AS (

   SELECT CAST('2016-01-01' AS DATE) AS [workingDays]
   UNION ALL

   SELECT DATEADD(DAY, 1, workingdays)
   FROM DatesCTE
   WHERE DATEADD(DAY, 1, workingdays) < '2017-01-01'

)

SELECT *
FROM DatesCTE
WHERE ((DATEPART(dw, workingDays) + @@DATEFIRST) % 7) NOT IN (0, 1)
OPTION (MAXRECURSION 366)

答案 1 :(得分:2)

首先在表格中填写年份的所有日期(例如2016年):

DECLARE @date_start date = '2016-01-01',
        @date_end date = '2016-12-31';

WITH cte as (
SELECT @date_start as [d], 0 as Level
UNION ALL
SELECT DATEADD(day,1,[d]), [level] + 1 as [level]
from cte
WHERE [level] < DATEDIFF(day,@date_start,@date_end)
),

holidays as ( --table with holidays
SELECT * FROM (VALUES
('2016-01-01'),
('2016-01-18'),
('2016-02-15'),
('2016-05-30'),
('2016-07-04'),
('2016-09-05'),
('2016-10-10'),
('2016-11-11'),
('2016-11-24'),
('2016-12-26')) as t(d)
)

SELECT c.d
FROM cte c
LEFT JOIN holidays h on c.d=h.d
    WHERE DATEPART(WEEKDAY,d) NOT IN (1,7)  --will show only monday-friday
AND AND h.d is NULL
    OPTION (MAXRECURSION 1000); --if you need more than 3 years get MAXRECURSION up

答案 2 :(得分:2)

一个简单的循环可以:

declare @d date = '20160101';
while @d <= '20161231'
begin
    if datepart(weekday, @d) not in (1, 7) and <@d not a holiday>
        insert into working_days ("date") values (@d);
    set @d = dateadd(day, 1, @d);
end