sql >> Databasteknik >  >> RDS >> Sqlserver

Kontrollerar om tidsintervall överlappar, väktarproblemet [SQL]

Här är ett sätt att förenkla datumintervall som detta

Start          | End
2009-1-1 06:00 | 2009-1-1 18:00
2009-2-1 20:00 | 2009-2-2 04:00
2009-2-2 06:00 | 2009-2-2 14:00

Du måste jämföra föregående och nästa datum i varje rad och se om

  • Aktuell rads Start datum ligger mellan föregående rads datumintervall.
  • Aktuell rads slut datumet ligger mellan nästa rads datumintervall.

Genom att använda ovanstående kod är det så enkelt att implementera UDF som följs.

create function fnThereIsWatchmenBetween(@from datetime, @to datetime)
returns bit
as
begin
    declare @_Result bit

    declare @FlattenedDateRange table (
        Start   datetime,
        [End]   datetime
    )

    insert  @FlattenedDateRange(Start, [End])
    select  distinct 
            Start = 
                case 
                    when Pv.Start is null then Curr.Start 
                    when Curr.Start between Pv.Start and Pv.[End] then Pv.Start
                    else Curr.Start 
                end,
            [End] = 
                case 
                    when Curr.[End] between Nx.Start and Nx.[End] then Nx.[End] 
                    else Curr.[End] 
                end
    from    shift Curr
            left join shift Pv on Pv.ID = Curr.ID - 1 --; prev
            left join shift Nx on Nx.ID = Curr.ID + 1 --; next

    if exists(  select  1
                from    FlattenedDateRange R
                where   @from between R.Start and R.[End]
                        and @to between R.Start and R.[End]) begin
        set @_Result = 1    --; There is/are watchman/men during specified date range
    end
    else begin
        set @_Result = 0    --; There is NO watchman
    end

    return @_Result
end


  1. Hur uppgraderar jag MySQL-databasschemat?

  2. MySQL - Räkna rader och vänster join problem

  3. Hur kan jag använda delsträng i SQL?

  4. Pgsql-fel:Du kan behöva lägga till casts av explicit typ