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

后端 未结 2 1331
忘掉有多难
忘掉有多难 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:28

    I solved that (well, in a way) very efficiently by creating a dumb table having the date and time (accurate be the minute) in one column (PK) and a bit in the second. A '1' meant, the user is available and 0 meant, he/she's not.

    The rest is dead simple. I was sick of having to write endless complicated queries in trying to get the minutes in partly overlapping time ranges.

    In fact, this was for computing machine efficiency.

    I know this is not the real deal but the most simple solution I came up with. You might create a function/SP which creates that table..

    0 讨论(0)
  • 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.

    0 讨论(0)
提交回复
热议问题