TSQL - 难以分组

Ale*_*ec. 2 sql-server grouping windowed

请参阅小提琴:http://sqlfiddle.com/#!6/ e6768/2

我有数据,如下所示:

DRIVER  DROP
1       1
1       2
1       ReturnToBase
1       4
1       5
1       ReturnToBase
1       6
1       7    
2       1
2       2
2       ReturnToBase
2       4
Run Code Online (Sandbox Code Playgroud)

我正在尝试对数据进行分组,因此对于每个驱动程序,每组返回基数都有一个分组编号.

我的输出应该如下所示:

DRIVER      DROP           GROUP
1            1              1
1            2              1
1            ReturnToBase   1
1            4              2
1            5              2
1            ReturnToBase   2
1            6              3
1            7              3
1            ReturnToBase   3               
2            1              1           
2            2              1
2            ReturnToBase   1   
2            4              2
Run Code Online (Sandbox Code Playgroud)

我尝试使用窗口函数的组合来获得这个结果,但到目前为止我已经离开了

下面是我到目前为止所做的,它不应该是功能性的我试图弄清楚它是如何完成的,如果它甚至可能的话.

SELECT 
    ROW_NUMBER() OVER (Partition BY Driver order by Driver Desc) rownum,
    Count(1) OVER (Partition By Driver Order By Driver Desc) counter,
    Count
    DropNo,
    Driver,
    CASE DropNo 
       WHEN 'ReturnToBase' THEN 1 ELSE 0 END AS EnumerateRound
FROM 
    Rounds
Run Code Online (Sandbox Code Playgroud)

Gio*_*sos 5

您可以使用以下查询:

SELECT id, DRIVER, DROPno, 
       1 + SUM(flag) OVER (PARTITION BY DRIVER ORDER BY id) -
       CASE 
          WHEN DROPno = 'ReturnToBase' THEN 1 
          ELSE 0 
       END AS grp       
FROM (
  SELECT id, DRIVER, DROPno, 
         CASE 
            WHEN DROPno = 'ReturnToBase' THEN 1 
            ELSE 0 
         END AS flag
  FROM rounds ) AS t
Run Code Online (Sandbox Code Playgroud)

在这里演示

此查询使用子句中的窗口版本SUMwith 来计算运行总计.此版本可从SQL Server 2012开始提供AFAIK.ORDER BYOVERSUM

为了获得正确的GROUP值,我们需要摆弄这个运行总值.

编辑:(信用转到@Conrad Frix)

使用CROSS APPLY而不是内联视图可以大大简化:

SELECT id, DRIVER, DROPno, 
       1 + SUM(x.flag) OVER (PARTITION BY DRIVER ORDER BY id) - x.flag
FROM rounds
CROSS APPLY (SELECT CASE WHEN DROPno = 'ReturnToBase' THEN 1 ELSE 0 END) AS x(flag)
Run Code Online (Sandbox Code Playgroud)

在这里演示