SQL服务器Window函数根据前后行是否属于同一类型按顺序分配组
SQL Server Window Function assign groups by order based on whether or not the row before or after is of the same type
有没有办法在SQL服务器中使用window函数按列排序,然后根据前后行是否属于同一类型来分配组?
假设 table [tbl1]
SELECT * FROM tbl1 ORDER BY SEQ
生成此输出。
SEQ Type
1 a
2 a
3 b
4 a
5 c
6 c
你能用 window 函数产生这个结果吗?
SEQ Type Group
1 a 1
2 a 1
3 b 2
4 a 3
5 c 4
6 c 4
请注意,第 4 行被视为一个单独的组,因为第 3 行或第 5 行不是类型 'a'。
您可以使用不同的行号来做到这一点。这是一种产生序列号的方法
select seq, type,
dense_rank() over (order by grp, type)
from (select t.*,
(row_number() over (order by seq) -
row_number() over (partition by type order by seq)
) as grp
from tbl1 t
) t;
请注意,这允许 seq
中存在间隙。如果没有间隙,您可以将第一个 row_number()
替换为 seq
.
这是基于 LAG
和 SUM
的不同解决方案,具有 OVER (ORDER BY ...)
window 功能,可从 SQL Server 2012 起获得:
SELECT SEQ, Type, SUM(flag) OVER(ORDER BY SEQ) + 1 AS [Group]
FROM (
SELECT *, CASE WHEN LAG(Type) OVER(ORDER BY SEQ) <> Type THEN 1
ELSE 0
END AS flag
FROM #tbl1 ) t
这个子查询:
SELECT *, CASE WHEN LAG(Type) OVER(ORDER BY SEQ) <> Type THEN 1
ELSE 0
END AS flag
FROM #tbl1
产生此输出(基于 OP 的示例数据):
SEQ Type flag
----------------
1 a 0
2 a 0
3 b 1
4 a 1
5 c 1
6 c 0
flag
表示 Type
的变化。外部查询将组数计算为 运行 总数 of flag
.
输出:
SEQ Type Group
--------------
1 a 1
2 a 1
3 b 2
4 a 3
5 c 4
6 c 4
有没有办法在SQL服务器中使用window函数按列排序,然后根据前后行是否属于同一类型来分配组?
假设 table [tbl1]
SELECT * FROM tbl1 ORDER BY SEQ
生成此输出。
SEQ Type
1 a
2 a
3 b
4 a
5 c
6 c
你能用 window 函数产生这个结果吗?
SEQ Type Group
1 a 1
2 a 1
3 b 2
4 a 3
5 c 4
6 c 4
请注意,第 4 行被视为一个单独的组,因为第 3 行或第 5 行不是类型 'a'。
您可以使用不同的行号来做到这一点。这是一种产生序列号的方法
select seq, type,
dense_rank() over (order by grp, type)
from (select t.*,
(row_number() over (order by seq) -
row_number() over (partition by type order by seq)
) as grp
from tbl1 t
) t;
请注意,这允许 seq
中存在间隙。如果没有间隙,您可以将第一个 row_number()
替换为 seq
.
这是基于 LAG
和 SUM
的不同解决方案,具有 OVER (ORDER BY ...)
window 功能,可从 SQL Server 2012 起获得:
SELECT SEQ, Type, SUM(flag) OVER(ORDER BY SEQ) + 1 AS [Group]
FROM (
SELECT *, CASE WHEN LAG(Type) OVER(ORDER BY SEQ) <> Type THEN 1
ELSE 0
END AS flag
FROM #tbl1 ) t
这个子查询:
SELECT *, CASE WHEN LAG(Type) OVER(ORDER BY SEQ) <> Type THEN 1
ELSE 0
END AS flag
FROM #tbl1
产生此输出(基于 OP 的示例数据):
SEQ Type flag
----------------
1 a 0
2 a 0
3 b 1
4 a 1
5 c 1
6 c 0
flag
表示 Type
的变化。外部查询将组数计算为 运行 总数 of flag
.
输出:
SEQ Type Group
--------------
1 a 1
2 a 1
3 b 2
4 a 3
5 c 4
6 c 4