使用SQl2008 R2。我有一大组记录(100k)按特定顺序排序(我在我的样本数据中使用了ID)。我必须保持这个序列
我想在设置字段更改时增加组。我认为使用窗口函数会很容易,但我已经卡住了
我的数据是
ID Letter Number 1 A 1 2 B 2 3 B 2 4 B 2 5 A 1
需要的结果是
ID Letter Number GroupID 1 A 1 1 2 B 2 2 3 B 2 2 4 B 2 2 5 A 1 3
基本上,当Col1和Col2的组合在WHT SORTED时改变时,我想增加groupno。即使第1行和第5行都包含A 1,它们必须具有唯一的GroupNos,因为它们被2,3,4插入
(我的真实数据包含几个需要比较的字段)
-- Create tables to work with / Source and Destination
CREATE TABLE #Items
(
ID INT
,Letter VARCHAR(1)
,Number INT
)
CREATE TABLE #Results
(
ID INT
,Letter VARCHAR(1)
,Number INT
,GroupID int
)
INSERT INTO #Items
( ID,Letter, Number )
SELECT 1, 'A', 1
UNION
SELECT 2, 'B', 2
UNION
SELECT 3,'B', 2
UNION
SELECT 4, 'B', 2
UNION
SELECT 5, 'A', 1
SELECT * FROM #Items
ORDER BY ID
INSERT INTO #Results
( ID,Letter, Number, GroupID )
SELECT 1, 'A', 1, 1
UNION
SELECT 2, 'B', 2,2
UNION
SELECT 3,'B', 2,2
UNION
SELECT 4, 'B', 2,2
UNION
SELECT 5, 'A', 1,3
提前致谢
标记
答案 0 :(得分:2)
解决此问题的一种简单方法是两个行号的差异。这唯一地标识了每个值序列。然后使用dense_rank()
。这是查询:
select ID, Letter, Number,
dense_rank() over (order by diff, letter) as GroupId
from (select i.*,
(row_number() over (order by id) -
row_number() over (partition by letter order by id)
) as diff
from #items i
) t
根据您的数据,这里是行号,差异和最终值的样子:
ID Letter Number RN-ID RN-Letter Diff GroupId
1 A 1 1 1 0 1
2 B 2 2 1 1 2
3 B 2 3 2 1 2
4 B 2 4 3 1 2
5 A 1 5 2 3 3
瞧!几乎像魔术一样。
Here就是SQL Fiddle的例子。
答案 1 :(得分:1)
您可以使用具有自联接的公用表表达式来模拟SQL Server 2012的LAG
并检测更改。 cte的原因是确保行号是连续的,因为id
可能不是;
WITH cte AS ( SELECT *, ROW_NUMBER() OVER (ORDER BY id) rn FROM #items )
SELECT a.id, a.letter, a.number,
1 + SUM(CASE WHEN a.letter<>b.letter OR a.number<>b.number THEN 1 ELSE 0 END)
OVER (ORDER BY a.id) groupid
FROM cte a LEFT JOIN cte b ON a.rn = b.rn + 1
ORDER BY a.id
SQLfiddle现在有点累,所以无法添加一个。这是在SQL Server 2012上测试的,但 应该在2008R2上运行。