Home > Software design >  SQL Building time ranges from sequential columns
SQL Building time ranges from sequential columns

Time:08-30

I have a table with three columns.
DAYOFWEEK, STARTTIME, and ENDTIME. For many of the rows (sorted by STARTTIME) the STARTTIME is equal to the previous ENDTIME. I need to create ranges where those times are concurrent.

Sample Data:

DAYOFWEEK STARTTIME ENDTIME
1 61200 62100
1 62100 63000
1 63000 63900
1 63900 64800
1 64800 65700
1 68800 69900
2 51000 52000

Based on the sample data I'm seeking:

DAYOFWEEK STARTTIME ENDTIME
1 61200 65700
1 68800 69900
2 51000 52000

I'm sure it can be done somehow with CTE's and/or LAG/LEAD but I just can't work it out. Any brilliant ideas out there? I'm limited to using SQL 2014. Thanks!

CodePudding user response:

This could work:

WITH
indata(dayofweek,starttime,endtime) AS (
          SELECT 1,61200,62100
UNION ALL SELECT 1,62100,63000
UNION ALL SELECT 1,63000,63900
UNION ALL SELECT 1,63900,64800
UNION ALL SELECT 1,64800,65700
UNION ALL SELECT 1,68800,69900
)
,
w_neighbours AS (
SELECT
    *
  , COALESCE(
      LAG(endtime   ) OVER (PARTITION BY dayofweek ORDER BY starttime)
    , starttime
    ) AS lastend
  , COALESCE(
      LEAD(starttime) OVER (PARTITION BY dayofweek ORDER BY starttime)
    , endtime  
    ) AS nextstart
  FROM indata
  -- ctl SELECT * from w_neighbours
  -- ctl  dayofweek | starttime | endtime | lastend | nextstart 
  -- ctl ----------- ----------- --------- --------- -----------
  -- ctl          1 |     61200 |   62100 |   61200 |     62100
  -- ctl          1 |     62100 |   63000 |   62100 |     63000
  -- ctl          1 |     63000 |   63900 |   63000 |     63900
  -- ctl          1 |     63900 |   64800 |   63900 |     64800
  -- ctl          1 |     64800 |   65700 |   64800 |     68800
  -- ctl          1 |     68800 |   69900 |   65700 |     69900
)
SELECT
  dayofweek
, starttime
, endtime
FROM w_neighbours
WHERE starttime - lastend > 0
   OR nextstart - endtime > 0
;
-- out  dayofweek | starttime | endtime 
-- out ----------- ----------- ---------
-- out          1 |     64800 |   65700
-- out          1 |     68800 |   69900

  • Related