使用SQL Server查找两个日期之间的假期列表

时间:2014-02-04 19:32:49

标签: sql-server

我试图从约会表中获取与时间跨度重叠的假期列表。例如,圣诞假期是24日星期三到26日星期五,当下面的约会重叠时,我需要返回这个假期。

假期表:

HolidayID     Name              StartDate     EndDate  
---------     ---------------   ----------    ----------  
1             Christmas Break   12/24/2014    12/26/2014  

约会表:

AppointmentID     PatientID     AppointmentDateTime   AppointmentDuration  
-------------     ---------     -------------------   -------------------  
1                 345           12/23/2014T23:00:00     02:00:00.0000000  

有人能指出我正确的方向吗?

4 个答案:

答案 0 :(得分:1)

没有表格的版本 我的国家/地区的本地节日(土耳其) 其中包括一些与回历一起使用的宗教节日;

    create FUNCTION [dbo].[fn_IsItHoliday](@Tarih datetime) 
    RETURNS bit
    AS
    BEGIN 

    RETURN case 
    when CONVERT(nchar,@Tarih,131) like ' 2/10/%' then 1 --'Ramazan Bayramı 1.Günü'
    when CONVERT(nchar,@Tarih,131) like ' 3/10/%' then 1 --'Ramazan Bayramı 2.Günü'
    when CONVERT(nchar,@Tarih,131) like ' 4/10/%' then 1 --'Ramazan Bayramı 3.Günü'
    when CONVERT(nchar,@Tarih,131) like '10/12/%' then 1 --'Kurban Bayramı 1.Günü'
    when CONVERT(nchar,@Tarih,131) like '11/12/%' then 1 --'Kurban Bayramı 2.Günü'
    when CONVERT(nchar,@Tarih,131) like '12/12/%' then 1 --'Kurban Bayramı 3.Günü'
    when CONVERT(nchar,@Tarih,131) like '13/12/%' then 1 --'Kurban Bayramı 4.Günü'
    when CONVERT(varchar,@Tarih, 121) like '____-01-01%' then 1 --'Yılbaşı'
    when CONVERT(varchar,@Tarih, 121) like '____-04-23%' then 1 --'Ulusal Egemenlik ve Çocuk Bayramı'
    when CONVERT(varchar,@Tarih, 121) like '____-05-19%' then 1 --'Atatürk’ü Anma Gençlik ve Spor Bayramı'
    when CONVERT(varchar,@Tarih, 121) like '____-07-15%' then 1 --'Demokrasi Bayramı'
    when CONVERT(varchar,@Tarih, 121) like '____-08-30%' then 1 --'Zafer Bayramı'
    when CONVERT(varchar,@Tarih, 121) like '____-10-29%' then 1 --'Cumhuriyet Bayramı'
    else 0 end

    END


declare @Date Datetime, @Year int
set @Date = '2018-01-01'
set @Year = Year(@Date)

    while year(@Date)=@Year
    begin
        if [dbo].[fn_IsItHoliday](@Date)
        ---
            --here you can list your holidays however you like
        ---
        set @Date=dateadd(day,1,@Date)
    end

答案 1 :(得分:0)

当一个在第二个结束之前开始而第一个在第二个结束之后结束时,两个时间段重叠。您可以在查询中使用此逻辑:

select a.*, h.Name
from Appointments a join
     Holidays h
     on h.EndDate >= cast(a.AppointmentDate as date) and
        h.StartDate <= cast(a.AppointmentDate + a.AppointmentDuration as date);

答案 2 :(得分:0)

试试这个,也许......

    SELECT h.* FROM Holidays h 
    JOIN (SELECT *,
        DATEADD(hour, a.AppointmentDuration, a.AppointmentDateTime) [AppointmentEnd]
        FROM Appointments a) aa ON aa.AppointmentDateTime BETWEEN h.StartDate AND h.EndDate
    OR aa.AppointmentEnd BETWEEN h.StartDate AND h.EndDate
    WHERE aa.AppointmentId = 1

答案 3 :(得分:0)

这是一个有效的SQL小提琴:http://sqlfiddle.com/#!3/e01d3/3

使用SQL:

SELECT AppointmentID
    , PatientID
    , Name AS HolidayName
FROM Appointment A JOIN Holiday H
ON A.AppointmentDateTime BETWEEN H.StartDate AND H.EndDate

创建表格和插入数据

CREATE TABLE Holiday
(
    HolidayID INT NOT NULL,
    Name NVARCHAR(100) NOT NULL,
    StartDate DATE NOT NULL,
    EndDate  DATE NOT NULL
);

INSERT INTO Holiday VALUES
(1,'Christmas Break','12/24/2014','12/26/2014'),
(2,'New Year Eve','12/31/2014','12/31/2014');

CREATE TABLE Appointment
(
    AppointmentID INT NOT NULL,
    PatientID INT NOT NULL,
    AppointmentDateTime DATETIME NOT NULL,
    AppointmentDuration  TIME NULL
);

INSERT INTO Appointment VALUES
(1, 345, '12/25/2014 23:00:00','02:00:00.0000000');

运行SQL

SELECT AppointmentID
    , PatientID
    , Name AS HolidayName
FROM Appointment A JOIN Holiday H
ON A.AppointmentDateTime BETWEEN H.StartDate AND H.EndDate

结果

APPOINTMENTID   PATIENTID   HOLIDAYNAME
1               345         Christmas Break