查找连续序列并建议序列中的下一个数字
Posted
技术标签:
【中文标题】查找连续序列并建议序列中的下一个数字【英文标题】:Find consecutive sequence and suggest next number in sequence 【发布时间】:2021-12-09 15:52:33 【问题描述】:我正在尝试创建一个程序,它将:
将任何数字作为输入,例如102
找到它所属的序列范围,例如100 to 103
向用户返回建议的下一个号码,例如104
表格本身看起来像这样:
Num |
---|
100 |
101 |
102 |
103 |
110 |
111 |
112 |
113 |
114 |
115 |
120 |
121 |
理想情况下,查询的输出会返回如下内容:
start | end | nextNr |
---|---|---|
100 | 103 | 104 |
110 | 115 | 116 |
120 | 121 | 122 |
我正在尝试做的这件事与某种间隙和孤岛技术有关。 我看了看从这里尝试一些东西,但无法让它发挥作用。 Gaps and Islands Link
这是我尝试过的……
WITH cteSource(ID, Seq, Num)
AS(
SELECT d.ID, f.Seq, f.Num
FROM (
SELECT
ID,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY MIN(SeqNo)) AS Grp,
MIN(SeqNo) AS StartSeqNo,
MAX(SeqNo) AS EndSeqNo
FROM
(
SELECT 1 ID, Num SeqNo,
Num - ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY Num) AS RN
FROM
Number
) AS a
GROUP BY ID, RN
) d
CROSS APPLY (
VALUES (d.Grp, d.EndSeqNo + 1),(d.Grp -1, d.StartSeqNo -1)
) AS f(Seq, Num)
)
SELECT ID, MIN(Num) AS StartSeqNo, MAX(Num) AS EndSeqNo, MAX(Num) + 1 as NextNr
FROM cteSource
GROUP BY ID, Seq
HAVING COUNT(*) = 2
结果如下:
StartSeqNo | EndSeqNo | NextNr |
---|---|---|
104 | 109 | 110 |
116 | 119 | 120 |
设置如下:
CREATE TABLE [dbo].[Number](
[Num] [int] NULL
)
GO
INSERT INTO Number
(Num)
VALUES
(100),
(101),
(102),
(103),
(110),
(111),
(112),
(113),
(114),
(115),
(120),
(121)
【问题讨论】:
【参考方案1】:也许这会有所帮助。
Select [Start] = min(num)
,[End] = max(num)
,[NextNr] = max(num) + 1
From (
Select *
,Grp = num - row_number() over (order by num)
From number
) A
Group By Grp
结果
Start End NextNr
100 103 104
110 115 116
120 121 122
【讨论】:
这真是……太棒了! 哇,这么简单...我如何确保NextNr
不会意外进入下一个序列?在我发布之后才意识到这可能会发生......
@Justin 如果 NextNr 可以进入下一个序列,这意味着那里没有间隙,并且结果序列看起来不会像那样。【参考方案2】:
您的第一个子查询可以很好地获取组以及开始和结束编号:
SELECT
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY MIN(SeqNo)) AS Grp,
MIN(SeqNo) AS StartSeqNo,
MAX(SeqNo) AS EndSeqNo
FROM
(
SELECT 1 ID, Num SeqNo,
Num - ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY Num) AS RN
FROM
Number
) AS a
GROUP BY ID, RN
然后你就不必要地把它复杂化了,而不是仅仅为 NextNr 使用 EndSeqNo + 1:
WITH CTE_Groups AS
(
SELECT
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY MIN(SeqNo)) AS Grp,
MIN(SeqNo) AS StartSeqNo,
MAX(SeqNo) AS EndSeqNo
FROM
(
SELECT 1 ID, Num SeqNo,
Num - ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY Num) AS RN
FROM
Number
) AS a
GROUP BY ID, RN
)
SELECT *, EndSeqNo + 1 AS NextNr
FROM
CTE_Groups
编辑:并进一步删除不必要的分区和额外的列
WITH CTE_Groups AS
(
SELECT
MIN(SeqNo) AS StartSeqNo,
MAX(SeqNo) AS EndSeqNo
FROM
(
SELECT Num SeqNo,
Num - ROW_NUMBER() OVER (ORDER BY Num) AS RN
FROM
Number
) AS a
GROUP BY RN
)
SELECT *, EndSeqNo + 1 AS NextNr
FROM
CTE_Groups
【讨论】:
以上是关于查找连续序列并建议序列中的下一个数字的主要内容,如果未能解决你的问题,请参考以下文章