2

I have a table in which there are two columns StartTime and EndTime. Values are filled in it as:

 declare @tbl Table(
colA VARCHAR(50),
colS VARCHAR(50),
DATES DATE,
STARTTIME TIME,
ENDTIME TIME,
ID BIGINT NOT NULL IDENTITY(1,1)
)

INSERT INTO @tbl
SELECT 'A','S',convert(date,'2015-09-21'),convert(TIME,'12:45'),convert(TIME,'13:30')
UNION ALL
SELECT 'A','S',convert(date,'2015-09-21'),convert(TIME,'13:15'),convert(TIME,'13:45')
UNION ALL
SELECT 'A','S',convert(date,'2015-09-21'),convert(TIME,'13:30'),convert(TIME,'16:50')
UNION ALL
SELECT 'A','S',convert(date,'2015-09-21'),convert(TIME,'13:15'),convert(TIME,'13:50')

Hence, I want to check whether StartTime and EndTime in all rows of this table covers the whole time period between Minimum StartTime and Maximum EndTime of this table. Hence from these rows, it is clear that it is true. However for the following set of rows, it wont be true because of time gap in them. So I just want True or False as the result.

INSERT INTO @tbl
SELECT 'A','S',convert(date,'2015-09-21'),convert(TIME,'08:45'),convert(TIME,'09:15')
UNION ALL
SELECT 'A','S',convert(date,'2015-09-21'),convert(TIME,'11:10'),convert(TIME,'11:25')

I have managed to complete all other tasks and this is the end result of them. This is the final task and I am completely clueless how to do it. Any help would be appreciated.

4

4 に答える 4

2

一般に、間隔は任意の長さである可能性があるため、隣接する行を比較しても完全な解決にはほど遠いです。上記のコメントで引用されているItzik Ben-GanのPacking Intervalsソリューションに加えて、別の完全なソリューションは、毎分(または他の粒度)をチェックすることです。

select uncoverdMinutes=count(*) -- 0 is true
from(
    select colA, colS, t.m
    from ( 
        select colA, colS
          , mst = min(starttime)
          , cnt = datediff(minute, min(starttime), max(endtime)) + 1
        from @tbl
        group by colA, colS 
    ) prm 
    cross apply (
        select top(prm.cnt)
            m = dateadd(minute
                      ,row_number() over(order by (select null)) - 1
                      ,prm.mst)                                    
        from sys.all_objects -- use tally table instead, if you have one
        ) t
  ) mi
where not exists (
    select 1 
    from @tbl t
    where mi.m between t.starttime and t.endtime)
于 2016-06-25T16:12:55.533 に答える
1

次の行の時間間隔が次の行の間隔と交差しているかどうかを確認するのに十分な場合は、 OUTER APPLY が処理を実行する必要があります。

SELECT  t.*, 
        CASE WHEN t.ENDTIME between p.STARTTIME and p.ENDTIME OR p.ENDTIME IS NULL THEN 'TRUE' ELSE 'FALSE' END as Seq
FROM @tbl t
OUTER APPLY (
    SELECT TOP 1 * 
    FROM @tbl 
    WHERE t.STARTTIME < STARTTIME and t.colA = colA and t.colS = colS and t.DATES = DATES
    ORDER BY STARTTIME ASC) p
ORDER BY t.STARTTIME

指定されたデータの出力:

colA    colS    DATES       STARTTIME           ENDTIME             ID  Seq
A       S       2015-09-21  08:45:00.0000000    09:15:00.0000000    5   FALSE
A       S       2015-09-21  11:10:00.0000000    11:25:00.0000000    6   FALSE
A       S       2015-09-21  12:45:00.0000000    13:30:00.0000000    1   TRUE
A       S       2015-09-21  13:15:00.0000000    13:45:00.0000000    2   TRUE
A       S       2015-09-21  13:15:00.0000000    13:50:00.0000000    4   TRUE
A       S       2015-09-21  13:30:00.0000000    16:50:00.0000000    3   TRUE
于 2016-06-25T14:01:13.113 に答える
1

試す

;with a as (select *,row_number() over (order by DATES,starttime) rn from @tbl)

select a.*,
case when isnull(b.endtime,a.endtime)>=a.STARTTIME then 'true' else 'false' end 
 from a left join a b on a.rn=b.rn+1
于 2016-06-25T12:23:50.100 に答える