Find Total Minutes Ignoring Overlap (Convert Cursor based Answer to CTE)

后端 未结 2 1335
忘掉有多难
忘掉有多难 2021-01-14 05:59

There is an existing question that asked how to find how many minutes there are in multiple date ranges, ignoring overlaps.

The example data given is (userID isn\'t

2条回答
  •  爱一瞬间的悲伤
    2021-01-14 06:40

    The following query finds the periods in the data, according to your definition. It uses correlated subqueries first to determine whether a record is the start of a period (that is, no overlap with earlier time periods). It then assigns the "periodStart" as the most recent start that is the beginning of a non-overlapping period.

    The following (untested) query takes this approach:

    with TimeWithOverlap as (
         select t.*,
                (case when exists (select * from dbo.Available tbefore where t.availStart > tbefore.availStart and tbefore.availEnd >= t.availStart)
                      then 0
                      else 1
                 end) as IsPeriodStart
         from dbo.Available t 
        ),
        TimeWithPeriodStart as (
         select two.*,
                (select MAX(two1.AvailStart) from TimeWithOverlap two1 where IsPeriodStart = 1 and two1.AvailStart <= two.AvailStart
                ) as periodStart
         from TimeWithOverlap two
        )
    select periodStart, MAX(AvailEnd) as periodEnd
    from TimeWithPeriodStart twps
    group by periodStart;
    

    http://sqlfiddle.com/#!6/3483c/20 (Second Query)

    If two periods both start at the same time, then it still works, because the AvailStart values are the same. Because of the correlated subqueries, this might not perform very well on even medium sized data sets.

    There are other methods for approaching this. For instance, if you had SQL Server 2012, you would be able to use cumulative sum functions, which offer a simpler method.

提交回复
热议问题