Mar*_*ark 5 t-sql sql-server common-table-expression sql-server-2008
这对我来说是一个相当新的练习,但我需要找到一种方法来识别表格中的模式序列.例如,假设我有一个类似于以下内容的简单表:
现在我想做的是识别和分组所有具有值为5,9和6的序列模式的记录,并在查询中显示它们.你会如何使用T-SQL完成这项任务?
结果应如下所示:
我已经找到了一些可能实现这一目标的潜在例子,却找不到真正有用的东西.
您可以使用包含在a CTE
中的以下查询,以便将序列号分配给序列中包含的值:
;WITH Seq AS (
SELECT v, ROW_NUMBER() OVER(ORDER BY k) AS rn
FROM (VALUES(1, 5), (2, 9), (3, 6)) x(k,v)
)
Run Code Online (Sandbox Code Playgroud)
输出:
v rn
-------
5 1
9 2
6 3
Run Code Online (Sandbox Code Playgroud)
使用上面的方法,CTE
您可以识别孤岛,即包含整个序列的连续行的切片:
;WITH Seq AS (
SELECT v, ROW_NUMBER() OVER(ORDER BY k) AS rn
FROM (VALUES(1, 5), (2, 9), (3, 6)) x(k,v)
), Grp AS (
SELECT [Key], [Value],
ROW_NUMBER() OVER (ORDER BY [Key]) - rn AS grp
FROM mytable AS m
LEFT JOIN Seq AS s ON m.Value = s.v
)
SELECT *
FROM Grp
Run Code Online (Sandbox Code Playgroud)
输出:
Key Value grp
-----------------
1 5 0
2 9 0
3 6 0
6 5 3
7 9 3
8 6 3
Run Code Online (Sandbox Code Playgroud)
grp
字段可以帮助您准确识别这些岛屿.
您现在需要做的就是过滤掉部分组:
;WITH Seq AS (
SELECT v, ROW_NUMBER() OVER(ORDER BY k) AS rn
FROM (VALUES(1, 5), (2, 9), (3, 6)) x(k,v)
), Grp AS (
SELECT [Key], [Value],
ROW_NUMBER() OVER (ORDER BY [Key]) - rn AS grp
FROM mytable AS m
LEFT JOIN Seq AS s ON m.Value = s.v
)
SELECT g1.[Key], g1.[Value]
FROM Grp AS g1
INNER JOIN (
SELECT grp
FROM Grp
GROUP BY grp
HAVING COUNT(*) = 3 ) AS g2
ON g1.grp = g2.grp
Run Code Online (Sandbox Code Playgroud)
注意:这个答案的最初版本使用INNER JOIN
到Seq
.如果表包含类似的值5, 42, 9, 6
,这将无效,并且42
将被INNER JOIN
错误地识别为有效的序列过滤掉.感谢@HABO进行此编辑.
归档时间: |
|
查看次数: |
2144 次 |
最近记录: |