基于序列的SQL Server 2008组

时间:2015-02-26 10:31:14

标签: sql sql-server tsql group-by

我很难找到是否可以使用SQL Server 2008分配序列而不必使用游标。让我们说下面的表格定义了一个司机从一个地方到另一个地方的行车路线(null意味着他要从家里出发):

RouteID   SourceLocationID   DestinationLocationID  DriverID   Created   Updated
-------  ----------------   ---------------------   --------   -------   -------
 1        NULL               219                     1         10:20     10:23  
 2        219                266                     1         10:21     10:24
 3        266                NULL                    1         10:22     10:25
 4        NULL               54                      2         10:23     10:26
 5        54                 NULL                    2         10:24     10:27
 6        NULL               300                     1         10:25     10:28
 7        300                NULL                    1         10:26     10:29

我想在sourceLID为NULL且destinationLID为null的行之间对记录进行分组,因此我得到以下内容(为每个分组集生成序列号):

DriverID  DestinationLocationID   TripNumber
--------  ---------------------   ----------
 1         219                     1 (his first trip)
 1         266                     1
 1         300                     2 (his second trip)
 2         54                      1

有没有办法在这里使用GROUP BY而不是游标?

4 个答案:

答案 0 :(得分:2)

快速尝试:

with cte as
( select DestinationLocationID
       , DriverID
       , tripid = row_number() 
         over ( partition by driverid 
                order by DestinationLocationID)  
    from table1 
    where sourcelocationid is NULL
  UNION ALL
  select table1.DestinationLocationID
       , table1.DriverID
       , cte.tripid 
    from table1 
    join cte on  table1.SourceLocationID=cte.DestinationLocationID
             and table1.DriverID=cte.DriverID
    where cte.DestinationLocationID is not null
)
select * from cte

答案 1 :(得分:0)

试试这个:

select driverid, destinationlocationid, count(destinationlocationid) from 
(
select driverid, destinationlocationid from table1 where sourcelocationid is NULL
union all
select driverid, sourcelocationid from table1 where destinationlocationid is NULL
)A group by driverid, destinationlocationid

答案 2 :(得分:0)

使用相关的子查询来计算先前的行程,加1以获得此行程编号。

select DriverID,
       DestinationLocationID,
       (select count(*) + 1
        from routes t2
        where t1.DriverID = t2.DriverID
        and t1.RouteID > t2.RouteID
        and DestinationLocationID IS NULL) as TripNumber
from routes t1
where DestinationLocationID IS NOT NULL
order by DriverID, DestinationLocationID;

执行如下:

SQL>select DriverID,
SQL&       DestinationLocationID,
SQL&       (select count(*) + 1
SQL&        from routes t2
SQL&        where t1.DriverID = t2.DriverID
SQL&        and t1.RouteID > t2.RouteID
SQL&        and DestinationLocationID IS NULL) as TripNumber
SQL&from routes t1
SQL&where DestinationLocationID IS NOT NULL
SQL&order by DriverID, DestinationLocationID;
   DriverID DestinationLocationID   TripNumber
=========== ===================== ============
          1                   219            1
          1                   266            1
          1                   300            2
          2                    54            1

                  4 rows found

答案 3 :(得分:0)

试试这个,

Declare @t table(RouteID int, SourceLocationID int,DestinationLocationID int
,DriverID int,Created time, Updated time)
insert into @t
 values(1, NULL, 219, 1, '10:20','10:23'),  
 (2 ,219,266, 1, '10:21','10:24'), 
 (3,266, NULL, 1, '10:22','10:25'), 
 (4, NULL, 54, 2, '10:23','10:26'), 
 (5,54, NULL, 2, '10:24','10:27'), 
 (6,NULL,300, 1, '10:25','10:28'), 
 (7,300,NULL, 1, '10:26','10:29')

;

WITH CTE
AS (
    SELECT *
        ,ROW_NUMBER() OVER (
            PARTITION BY DriverID ORDER BY Created
            ) RN
    FROM @t
    )
    ,CTE1
AS (
    SELECT *
        ,1 TripNumber
    FROM CTE
    WHERE RN = 1

    UNION ALL

    SELECT A.*
        ,CASE 
            WHEN A.SourceLocationID IS NULL
                THEN B.TripNumber + 1
            ELSE B.TripNumber
            END
    FROM CTE1 B
    INNER JOIN CTE A ON B.DriverID = A.DriverID
    WHERE A.RN > B.RN
    )
SELECT DISTINCT DestinationLocationID
    ,DriverID
    ,TripNumber
FROM CTE1
WHERE DestinationLocationID IS NOT NULL
ORDER BY DriverID