选择连续出现多次的记录
Posted
技术标签:
【中文标题】选择连续出现多次的记录【英文标题】:Selecting records that appear several times in a row 【发布时间】:2021-04-09 14:51:52 【问题描述】:我的问题是我想选择一些连续出现的记录。 例如我们有这样的表:
x
x
x
y
y
x
x
y
查询应该给出这样的答案:
x 3
y 2
x 2
y 1
【问题讨论】:
您可能需要第二列。也许是一个自动增加的 id 列?如果您无法获得第二列,则在 excel 中也可能更容易。 请始终声明您的数据库系统和版本。 SQL 方言差异很大。 最后一个结果行y|1
与标题不一致。请澄清。
【参考方案1】:
SQL 表代表无序 集合。只有当有一列指定顺序时,您的问题才有意义。如果是这样,您可以使用差异行数来确定组,然后聚合:
select col1, count(*)
from (select t.*,
row_number() over (order by <ordering col>) as seqnum,
row_number() over (partition by col1 order by <ordering col>) as seqnum_2
from t
) t
group by col1, (seqnum - seqnum_2)
【讨论】:
抱歉,一定有什么地方出错了——它告诉我:'*' 附近的语法不正确。 @beginneeeeer2021 。 . .查询中唯一的*
s 是count(*)
和t.*
。两者在语法上都是正确的。
还有一个问题 - 2、6 和 6 行中的 t 是什么? :)
@beginneeeeer2021 。 . .那是from
子句中的表名和括号后面的表别名。您的问题没有指定表名,所以我只使用t
。【参考方案2】:
我做了一个 SQL Fiddle http://sqlfiddle.com/#!18/f8900/5
CREATE TABLE [dbo].[SomeTable](
[data] [nchar](1) NULL,
[id] [int] IDENTITY(1,1) NOT NULL
);
INSERT INTO SomeTable
([data])
VALUES
('x'),
('x'),
('x'),
('y'),
('y'),
('x'),
('x'),
('y')
;
select * from SomeTable;
WITH SomeTable_CTE (Data, total, BaseId, NextId)
AS
(
SELECT
Data,
1 as total,
Id as BaseId,
Id+1 as NextId
FROM SomeTable
where not exists(
Select * from SomeTable Previous
where Previous.Id+1 = SomeTable.Id
and Previous.Data = SomeTable.Data)
UNION ALL
select SomeTable_CTE.Data, SomeTable_CTE.total+1, SomeTable_CTE.BaseId as BaseId, SomeTable.Id+1 as NextId
from SomeTable_CTE inner join SomeTable on
SomeTable.Data = SomeTable_CTE.Data
and
SomeTable.Id = SomeTable_CTE.NextId
)
SELECT Data, max(total) as total
FROM SomeTable_CTE
group by Data, BaseId
order by BaseId
【讨论】:
【参考方案3】:房间里的大象是确定行顺序的缺失列。
SELECT col1, count(*)
FROM (
SELECT col1, order_column
, row_number() OVER (ORDER BY order_column)
- row_number() OVER (PARTITION BY col1 ORDER BY order_column) AS grp
FROM tbl
) t
GROUP BY col1, grp
ORDER BY min(order_column);
要排除只有一行的分区,请添加HAVING
子句:
SELECT col1, count(*)
FROM (
SELECT col1, order_column
, row_number() OVER (ORDER BY order_column)
- row_number() OVER (PARTITION BY col1 ORDER BY order_column) AS grp
FROM tbl
) t
GROUP BY col1, grp
HAVING count(*) > 1
ORDER BY min(order_column);
db小提琴here
添加最后一个 ORDER BY
以保持原始顺序(以及有意义的结果)。您可能还想添加min(order_column)
之类的列。
相关:
Find the longest streak of perfect scores per player Select longest continuous sequence Group by repeating attribute【讨论】:
这里的grp是什么? 只是别名是的? 看到AS grp
?这是计算的“组号”的列别名。链接答案中有充分的解释。我添加了另一个链接
还有一个问题:第 6 行和第 7 行应该有表 jest 的名称?例如 cattable 而不是 od t 和 tbl?因为我有一些错误语法
t
在我的查询中是来自子查询的派生表所需的别名。可以是任何个有效标识符。喜欢cattable
。 tbl
是基础表实际名称的占位符。以上是关于选择连续出现多次的记录的主要内容,如果未能解决你的问题,请参考以下文章