我有一个使用公司日历来跟踪所有工作日的 PostingPeriod 表。简化后,它看起来像这样:
Date Year Quarter Month Day IsWorkingDay
25.06.2015 2015 2 6 25 1
26.06.2015 2015 2 6 26 1
27.06.2015 2015 2 6 27 0
我有另一个表,其中包含所有采购行,其中包含订单日期、供应商确认的交货日期以及订单日期和交货日期之间工作日内允许的最长时间范围:
PurchID OrderDate ConfDelivery DeliveryDays
1234 14.04.2015 20.05.2015 30
1235 14.04.2015 24.05.2015 20
我想创建一个新列,返回每个订单的最大允许日期(无论工作日与否)。通常的方法(工作日/5 得到周数,乘以 7 得到天数)不起作用,因为需要考虑所有假期等。 由于这是用于为 OLAP 数据库提供数据的 DWH,因此性能不是问题。
最佳答案
您可以使用 ROW_NUMBER
为每个工作日分配一个任意索引,例如
SELECT Date, WorkingDayIndex = ROW_NUMBER() OVER(ORDER BY Date)
FROM dbo.Calendar
这会给你类似的东西:
Date WorkingDayIndex
-----------------------------
2015-04-27 80
2015-04-28 81
2015-04-29 82
2015-04-30 83
2015-05-01 84
2015-05-05 85
2015-05-06 86
2015-05-07 87
然后,如果您想知道距离给定日期 n 个工作日的日期,请找到索引 n 更高的日期,即 2015-04-27索引为 80,因此 5 个工作日后索引为 85,结果为 2015-05-05。
完整的工作示例
/***************************************************************************************************************************/
-- CREATE TABLES AND POPULATE WITH TEST DATA
SET DATEFIRST 1;
DECLARE @Calendar TABLE (Date DATE, IsWorkingDay BIT);
INSERT @Calendar
SELECT TOP 365 DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY object_id), '20141231'), 1 FROM sys.all_objects;
UPDATE @Calendar
SET IsWorkingDay = 0
WHERE DATEPART(WEEKDAY, Date) IN (6, 7)
OR Date IN ('2015-01-01', '2015-04-03', '2015-04-06', '2015-05-04', '2015-05-25', '2015-08-31', '2015-12-25', '2015-12-28');
DECLARE @T TABLE (PurchID INT, OrderDate DATE, ConfDeliveryDate DATE, DeliveryDays INT);
INSERT @T VALUES (1234, '20150414', '20150520', 30), (1235, '20150414', '20150524', 20);
/***************************************************************************************************************************/
-- ACTUAL QUERY
WITH WorkingDayCalendar AS
( SELECT *, WorkingDayIndex = ROW_NUMBER() OVER(ORDER BY Date)
FROM @Calendar
WHERE IsWorkingDay = 1
)
SELECT *
FROM @T AS t
INNER JOIN WorkingDayCalendar AS c1
ON c1.Date = t.OrderDate
INNER JOIN WorkingDayCalendar AS c2
ON c2.WorkingDayIndex = c1.WorkingDayIndex + t.DeliveryDays;
如果这是一个常见的要求,那么您可以将 WorkingDayIndex
设置为日历表中的一个固定字段,这样您就不需要在每次需要时都计算它。
关于sql - 将 X 个工作日添加到日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31052183/