没有周末和公众假期的SQL DateDiff

时间:2016-01-14 16:28:48

标签: tsql date-range date-difference

我正在寻找解决方案,如何在没有周末和公众假期的情况下选择两个日期之间的天数。

到目前为止,我有这个:

SELECT evnt.event_id,
       evnt.date_from,
       evnt.date_to,
       DATEDIFF(DD, evnt.date_from, evnt.date_to) 
       - (DATEDIFF(WK, evnt.date_from, evnt.date_to) * 2) 
       - CASE WHEN DATEPART(DW, evnt.date_from) = 1 THEN 1 ELSE 0 END 
       + CASE WHEN DATEPART(DW, evnt.date_to) = 1 THEN 1 ELSE 0 END AS Date_Diff
       --- COUNT(*) FROM public_holidays AS h WHERE h.date_from BETWEEN evnt.date_from AND evnt.date_to
       FROM events AS evnt

一切正常,直到我取消评论部分:

- COUNT(*) FROM public_holidays AS h WHERE h.date_from BETWEEN evnt.date_from AND evnt.date_to

我想要达到的目标是获得日期范围内的工作日数。问题出在最后一步,我试图从这个范围中减去所有公共假日。

任何人都可以帮助完成这最后一步吗?看来,我做错了什么,但我无法弄清楚是什么。

提前谢谢

6 个答案:

答案 0 :(得分:5)

试试这个:

--- COUNT(*) FROM public_holidays AS h WHERE h.date_from BETWEEN evnt.date_from AND evnt.date_to

取消注释应该是子查询

- (SELECT COUNT(*) FROM public_holidays AS h WHERE h.date_from BETWEEN evnt.date_from AND evnt.date_to)
像这样:

{{1}}

答案 1 :(得分:1)

Kajiyama,

试试这个:

SELECT evnt.event_id,
       evnt.date_from,
       evnt.date_to,
       DATEDIFF(DD, evnt.date_from, evnt.date_to) 
       - (DATEDIFF(WK, evnt.date_from, evnt.date_to) * 2) 
       - CASE WHEN DATEPART(DW, evnt.date_from) = 1 THEN 1 ELSE 0 END 
       + CASE WHEN DATEPART(DW, evnt.date_to) = 1 THEN 1 ELSE 0 END AS Date_Diff
       -(SELECT COUNT(*) FROM public_holidays AS h WHERE h.date_from BETWEEN evnt.date_from AND evnt.date_to)
       FROM events AS evnt

您似乎错过了SELECT

之前的COUNT(*)声明

答案 2 :(得分:1)

以下是WITH common_table_expression (CTE)

的不同答案
;with  t as
(
select COUNT(*) as cnt FROM public_holidays 
WHERE date_from BETWEEN evnt.date_from AND evnt.date_to
)
SELECT evnt.event_id,
       evnt.date_from,
       evnt.date_to,
       DATEDIFF(DD, evnt.date_from, evnt.date_to) 
       - (DATEDIFF(WK, evnt.date_from, evnt.date_to) * 2) 
       - CASE WHEN DATEPART(DW, evnt.date_from) = 1 THEN 1 ELSE 0 END 
       + CASE WHEN DATEPART(DW, evnt.date_to) = 1 THEN 1 ELSE 0 END AS Date_Diff
       - (select cnt from T)
       FROM events AS evnt

答案 3 :(得分:0)

(我看到这已经回答了,但我还是会把它扔掉......)

将每天作为一行的日历表可能不是一个坏主意,而不是单独的public_holidays表。查看文章SQL Server Calendar Table以获取可演示和可下载的T-SQL代码。包括几个用于查询和财政年度的后续文章。

答案 4 :(得分:0)

我看到了一些如下的示例elsewhere

如果您要查找“工作日差异”,请同时将其与正常的日历日差异(即DATEDIFF)进行比较。在两种情况下,两个相邻工作日之间的差值应为1天。其他解决方案需要在星期二至星期三之间的两个工作日内完成。

DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
SET @StartDate = '1/17/19'
SET @EndDate = '1/18/19'

-- CalendarDateDiff vs Business Date Diff
SELECT
    DATEDIFF(d, @StartDate, @EndDate) AS CalendarDateDiff
    , (DATEDIFF(dd, @StartDate, @EndDate) + 1) 
    -1
    -(DATEDIFF(wk, @StartDate, @EndDate) * 2)
    -(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN 1 ELSE 0 END)
    -(CASE WHEN DATENAME(dw, @EndDate) = 'Saturday' THEN 1 ELSE 0 END) AS CalendarDays

答案 5 :(得分:0)

三个标量函数:ShiftHolidayToWorkday,GetHoliday和GetWorkDays

// Views/BookThumbnailView.swift

import SwiftUI
import Foundation
import KingfisherSwiftUI

struct BookThumbnailView: View {
    @ObservedObject var viewModel: BookViewModel
        
    private var book: Book {
        viewModel.book
    }
    
    @ViewBuilder
    var body: some View {
        if let imageURL = self.viewModel.imageURL {
            if self.viewModel.imageURLIsReachable {
                KFImage(imageURL)
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(maxWidth: 70)
                        .cornerRadius(8)
            } else {
                ErrorBookThumbnailView()
            }
        } else {
            DefaultBookThumbnailView()
        }
    }
}