请参阅下面的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')
我正在寻找这样的输出:
ID为零将组分开。到目前为止我试过这个:
select * from (
select row_number() over (order by reference) as groupid, #test.* from #test
但是,在ID列中达到零时,groupid不会重置。
我意识到这是糟糕的设计。该表由外部公司创建。我只是在询问它。
答案 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,但这对大型表来说可能很麻烦。