如何使用日历参考 table 从 SQL 服务器中的给定日期计算工作日
How to count business days from a given date in SQL Server using a calendar reference table
我有两个 table。一个 table 是具有 date
列和 kindofday
列的日历。 kindofday
列包含 'bankday'、'saturday'、'sunday' 和 'holiday'。我需要考虑假期,否则网上有几个有用的查询...
date kindofday
1999-08-24 00:00:00:000 bankday
我正在努力构建一个可以计算从给定日期算起的工作日数的查询。类似于:
Select [date] + 12 business days
。我不确定如何使用日历 table 作为参考 - 本质上我需要在此日历 table 中找到一个日期,然后对该列倒计时数个工作日并提取该日期。我把它放在一个函数中,所以不用担心复杂性。可能有一个愚蠢的简单解决方案,我只是没有看到。
我愿意接受任何考虑假期的解决方案,即使他们不使用我的日历 table。我可以更改日历 table 但是我需要这样做才能使这项工作...即:使用 binary
而不是 string
'bankday' 等...
我试过这个:我从日历中删除了所有非银行日并添加了一个 integer
键,然后 set @date = (select key from calendar where @date=[date]
然后将工作日的数量添加到该键并返回日期,但问题是当 @date
是非银行日时它不会在日历中找到匹配项 table...
将问题改写为 "Of the next @count
bankdays after @start_date
, which one occurs last?"
SELECT @end_date = MAX(date)
FROM (
SELECT TOP(@count)
date
FROM Calendar
WHERE date > @start_date
AND kindofday = 'bankday'
ORDER BY date
) t
由于您使用的是 SQL 服务器,您可以使用 ranking 函数对非银行工作日进行排序并获得序列号,然后将其与您的天数相匹配想补充。
SELECT date
FROM (
SELECT date AS DATE,
ROW_NUMBER() OVER (ORDER BY date) AS PLUS_DAYS
FROM calendar
WHERE date > @start_date AND KINDOFDAY <> 'bankday'
ORDER BY date
) TEMP
WHERE TEMP.PLUS_DAYS = @plus_days
我偶然发现了这个较旧的问题,并对使用 window 函数回答以消除嵌套查询感到好奇
SELECT DISTINCT TOP (@count)
@end_date = MAX(date) OVER ()
FROM
Calendar
WHERE
date > @start_date
AND kindofday = 'bankday'
而现实是因为 MAX(date) OVER()
对每一行都是相同的,你甚至不需要 DISTINCT
。
SELECT TOP (@count)
@end_date = MAX(date) OVER ()
FROM
Calendar
WHERE
date > @start_date
AND kindofday = 'bankday'
这里有一个完整的例子供您参考:
DECLARE @end_date AS DATETIME
DECLARE @start_date AS DATETIME = '12/15/2016'
DECLARE @count INT = 12
;WITH Calendar AS (
SELECT
CAST('12/1/2016' AS DATETIME) as date
,'bankday' as kindofday
UNION ALL
SELECT
date + 1
,CASE
WHEN date + 1 = '12/25/2016' THEN 'holiday'
WHEN DATEPART(dw,date + 1) IN (1,7) THEN 'weekend'
ELSE 'bankday'
END
FROM
Calendar
WHERE date + 1 <= EOMONTH(date)
)
SELECT TOP (@count)
@end_date = MAX(date) OVER ()
FROM
Calendar
WHERE
date > @start_date
AND kindofday = 'bankday'
SELECT @end_date
我有两个 table。一个 table 是具有 date
列和 kindofday
列的日历。 kindofday
列包含 'bankday'、'saturday'、'sunday' 和 'holiday'。我需要考虑假期,否则网上有几个有用的查询...
date kindofday
1999-08-24 00:00:00:000 bankday
我正在努力构建一个可以计算从给定日期算起的工作日数的查询。类似于:
Select [date] + 12 business days
。我不确定如何使用日历 table 作为参考 - 本质上我需要在此日历 table 中找到一个日期,然后对该列倒计时数个工作日并提取该日期。我把它放在一个函数中,所以不用担心复杂性。可能有一个愚蠢的简单解决方案,我只是没有看到。
我愿意接受任何考虑假期的解决方案,即使他们不使用我的日历 table。我可以更改日历 table 但是我需要这样做才能使这项工作...即:使用 binary
而不是 string
'bankday' 等...
我试过这个:我从日历中删除了所有非银行日并添加了一个 integer
键,然后 set @date = (select key from calendar where @date=[date]
然后将工作日的数量添加到该键并返回日期,但问题是当 @date
是非银行日时它不会在日历中找到匹配项 table...
将问题改写为 "Of the next @count
bankdays after @start_date
, which one occurs last?"
SELECT @end_date = MAX(date)
FROM (
SELECT TOP(@count)
date
FROM Calendar
WHERE date > @start_date
AND kindofday = 'bankday'
ORDER BY date
) t
由于您使用的是 SQL 服务器,您可以使用 ranking 函数对非银行工作日进行排序并获得序列号,然后将其与您的天数相匹配想补充。
SELECT date
FROM (
SELECT date AS DATE,
ROW_NUMBER() OVER (ORDER BY date) AS PLUS_DAYS
FROM calendar
WHERE date > @start_date AND KINDOFDAY <> 'bankday'
ORDER BY date
) TEMP
WHERE TEMP.PLUS_DAYS = @plus_days
我偶然发现了这个较旧的问题,并对使用 window 函数回答以消除嵌套查询感到好奇
SELECT DISTINCT TOP (@count)
@end_date = MAX(date) OVER ()
FROM
Calendar
WHERE
date > @start_date
AND kindofday = 'bankday'
而现实是因为 MAX(date) OVER()
对每一行都是相同的,你甚至不需要 DISTINCT
。
SELECT TOP (@count)
@end_date = MAX(date) OVER ()
FROM
Calendar
WHERE
date > @start_date
AND kindofday = 'bankday'
这里有一个完整的例子供您参考:
DECLARE @end_date AS DATETIME
DECLARE @start_date AS DATETIME = '12/15/2016'
DECLARE @count INT = 12
;WITH Calendar AS (
SELECT
CAST('12/1/2016' AS DATETIME) as date
,'bankday' as kindofday
UNION ALL
SELECT
date + 1
,CASE
WHEN date + 1 = '12/25/2016' THEN 'holiday'
WHEN DATEPART(dw,date + 1) IN (1,7) THEN 'weekend'
ELSE 'bankday'
END
FROM
Calendar
WHERE date + 1 <= EOMONTH(date)
)
SELECT TOP (@count)
@end_date = MAX(date) OVER ()
FROM
Calendar
WHERE
date > @start_date
AND kindofday = 'bankday'
SELECT @end_date