SQL Query to group items by time, but only if near each other?

后端 未结 2 1676
遥遥无期
遥遥无期 2021-01-06 18:59

I am trying to craft a SQL statement to pull sample values from a DB. The table contains values that pertain to tool changes in a CNC machine. The current statement I have p

相关标签:
2条回答
  • 2021-01-06 19:36

    This is called the "islands problem" and I've seen this as a solution (credit Itzik Ben Gan)

    select  tool_number,
            min(time) 'in',
            max(time) 'out',
            count(*)
    from    (
        select  tool_number,
                time,
                ROW_NUMBER() OVER (ORDER BY time) - ROW_NUMBER() OVER (PARTITION BY Tool_Number ORDER BY time) AS Grp
        from    #temp
        ) as a
    group by grp, tool_number
    order by min(time)
    
    0 讨论(0)
  • 2021-01-06 19:39

    Here's another approach using LAG/LEAD:

    DECLARE @rawdata TABLE(Tool_Number INT, [Time] TIME(0));
    
    INSERT @rawdata VALUES
    (100,'12:00'), (100,'12:01'), (100,'12:02'), (100,'12:03'),
    (200,'12:04'), (200,'12:05'),
    (100,'12:06'), (100,'12:07');
    
    ;WITH x AS
    (
      SELECT Tool_Number, [Time], 
        s = CASE Tool_number WHEN LAG(Tool_number,1) OVER (ORDER BY [Time]) 
            THEN 0 ELSE 1 END,
        e = CASE Tool_number WHEN LEAD(Tool_number,1) OVER (ORDER BY [Time]) 
            THEN 0 ELSE 1 END
      FROM @rawdata
    ),
    y AS 
    (
      SELECT Tool_Number, s, [Time], e = LEAD([Time],1) OVER (ORDER BY [Time]) 
      FROM x WHERE 1 IN (s,e)
    )
    SELECT Tool_number, TIME_IN = [Time], TIME_OUT = e 
    FROM y 
    WHERE s = 1
    ORDER BY TIME_IN;
    

    Results:

    Tool_number  TIME_IN   TIME_OUT
    -----------  --------  --------
    100          12:00:00  12:03:00
    200          12:04:00  12:05:00
    100          12:06:00  12:07:00
    
    0 讨论(0)
提交回复
热议问题