我有一个表working_days
,其中一列date
的日期类型为
我需要在美国填写工作日。
你能建议我这样做吗?
手动太长了。
答案 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