使用row_number添加组ID列

时间:2016-05-17 09:27:30

标签: sql sql-server sql-server-2008-r2

请参阅下面的DDL:

create table #Test (reference int identity,id int,dataset varchar(10),primary key (reference))
insert into #Test (id,dataset) values (1,'System1')
insert into #Test (id,dataset) values (2,'System10')
insert into #Test (id,dataset) values (9,'System3')
insert into #Test (id,dataset) values (0,'')
insert into #Test (id,dataset) values (8,'System6')
insert into #Test (id,dataset) values (19,'System7')
insert into #Test (id,dataset) values (0,'')
insert into #Test (id,dataset) values (55,'System10')
insert into #Test (id,dataset) values (62,'System4')

我正在寻找这样的输出:

enter image description here

ID为零将组分开。到目前为止我试过这个:

select * from (
select  row_number() over (order by reference) as groupid, #test.* from #test

但是,在ID列中达到零时,groupid不会重置。

我意识到这是糟糕的设计。该表由外部公司创建。我只是在询问它。

3 个答案:

答案 0 :(得分:5)

试试这个:

SELECT *,
       COALESCE(SUM(CASE WHEN id = 0 THEN 1 END) 
                OVER (ORDER BY reference),0) + 1 AS GroupID
FROM #Test

查询使用带有SUM OVER子句的ORDER BY来计算0值的运行总计。如果我们向此运行总计添加1,我们会获得所需的GroupID值。

注意:此版本的SUM可从SQL Server 2012开始提供。

修改

您可以使用SUM OVER在旧版SQL Server中使用ORDER BY子句模拟OUTER APPLY,如下面的查询所示:

SELECT t1.*,
       x.cnt + 1 AS GroupID
FROM #Test t1
OUTER APPLY (SELECT COUNT(cASE WHEN id = 0 THEN 1 END) AS cnt
             FROM #Test t2
             WHERE t2.reference <= t1.reference) AS x

答案 1 :(得分:1)

In SQL Server 2012, the simplest way by using CTE.You can use this:

WITH CTE AS
(
  SELECT
      COALESCE(SUM(CASE WHEN ID = 0 THEN 1 END) OVER (ORDER BY reference),0)+ 1 AS GroupID,
      ID AS ID,
      dataset AS Dataset
  FROM 
     #Test 
)
SELECT * FROM CTE
WHERE ID !=0

答案 2 :(得分:0)

在SQL Server 2008中,最简单的方法是使用outer apply。我会这样做:

SELECT cume.GroupID, t.*
FROM #Test t OUTER APPLY
      (SELECT COUNT(*) as GroupID
       FROM #Test t2
       WHERE t2.reference <= t.reference AND t2.id = 0
      ) cume
WHERE t.id <> 0;

请注意,OP似乎不希望输出中包含0的行。将它们从外部查询中排除是安全的。

一种替代方法是使用递归CTE,但这对大型表来说可能很麻烦。