如何在SQL Server中查找非标识列中的间隙序列
我在下面这样的表中有一万多行,我想找出该列表序列号中缺失的空白如何在SQL Server中查找非标识列中的间隙序列,sql,asp.net,sql-server,sql-server-2008,Sql,Asp.net,Sql Server,Sql Server 2008,我在下面这样的表中有一万多行,我想找出该列表序列号中缺失的空白 CI-480-1617 CI-481-1617 CI-482-1617 CI-483-1617 CI-484-1617 CI-485-1617 CI-486-1617 CI-487-1617 CW-095-1617 你能帮我吗 谢谢如果没有样本数据,我无法测试解决方案,但在当前情况下,类似的内容可能会对您有所帮助: WITH CTE AS -- end previous statement with semi colon (
CI-480-1617
CI-481-1617
CI-482-1617
CI-483-1617
CI-484-1617
CI-485-1617
CI-486-1617
CI-487-1617
CW-095-1617
你能帮我吗
谢谢如果没有样本数据,我无法测试解决方案,但在当前情况下,类似的内容可能会对您有所帮助:
WITH CTE AS -- end previous statement with semi colon
(
SELECT SUBSTRING (ColumnA, 4,3) AS SeqNumb,
ROW_NUMBER() OVER (PARTITION BY SUBSTRING (ColumnA, 4,3) ORDER BY (SELECT 1)) AS RowNumb
FROM TableA
)
SELECT C.*, C2.RowNumb - C.RowNumb AS Gap
FROM CTE AS C
LEFT JOIN CTE AS C2 ON C.RowNumb = C2.RowNumb - 1
此解决方案基于一些假设,可以帮助您:
- 每行的第一部分是节
- 每行的第二部分是ID
CREATE TABLE [dbo].[Gaps] (
[Text] nvarchar(50) NOT NULL
);
INSERT [dbo].[Gaps] ([Text])
VALUES
('CI-480-1617'),
('CI-481-1617'),
('CI-482-1617'),
('CI-483-1617'),
('CI-484-1617'),
('CI-485-1617'),
('CI-486-1617'),
('CI-487-1617'),
('CW-095-1617');
WITH IDS (Section, Nmr) AS (
SELECT
SUBSTRING([Text], 1, CHARINDEX('-', [Text]) - 1),
CONVERT(int, SUBSTRING([Text], CHARINDEX('-', [Text]) + 1, CHARINDEX('-', [Text], CHARINDEX('|', [Text]))))
FROM Gaps
UNION ALL
SELECT
DISTINCT SUBSTRING([Text], 1, CHARINDEX('-', [Text]) - 1),
0
FROM Gaps
-- Uncomment next lines if you want to get the gap to some MAX value
--UNION ALL
--SELECT
-- DISTINCT SUBSTRING([Text], 1, CHARINDEX('-', [Text]) - 1),
-- 1000
--FROM Gaps
)
SELECT Section, StartNmr = cur + 1, EndNmr = nxt - 1
FROM (
SELECT
Section,
cur = Nmr,
nxt = (
SELECT MIN(B.Nmr)
FROM IDS AS B
WHERE B.Section = A.Section AND B.Nmr > A.Nmr
)
FROM IDS AS A
) AS D
WHERE nxt - cur > 1
ORDER BY Section, StartNmr
-----------------------
Section StartNmr EndNmr
-----------------------
CI 1 479
CW 1 94
-----------------------
Section StartNmr EndNmr
-----------------------
CI 1 479
CI 488 999
CW 1 94
CW 96 999
寻找差距:
CREATE TABLE [dbo].[Gaps] (
[Text] nvarchar(50) NOT NULL
);
INSERT [dbo].[Gaps] ([Text])
VALUES
('CI-480-1617'),
('CI-481-1617'),
('CI-482-1617'),
('CI-483-1617'),
('CI-484-1617'),
('CI-485-1617'),
('CI-486-1617'),
('CI-487-1617'),
('CW-095-1617');
WITH IDS (Section, Nmr) AS (
SELECT
SUBSTRING([Text], 1, CHARINDEX('-', [Text]) - 1),
CONVERT(int, SUBSTRING([Text], CHARINDEX('-', [Text]) + 1, CHARINDEX('-', [Text], CHARINDEX('|', [Text]))))
FROM Gaps
UNION ALL
SELECT
DISTINCT SUBSTRING([Text], 1, CHARINDEX('-', [Text]) - 1),
0
FROM Gaps
-- Uncomment next lines if you want to get the gap to some MAX value
--UNION ALL
--SELECT
-- DISTINCT SUBSTRING([Text], 1, CHARINDEX('-', [Text]) - 1),
-- 1000
--FROM Gaps
)
SELECT Section, StartNmr = cur + 1, EndNmr = nxt - 1
FROM (
SELECT
Section,
cur = Nmr,
nxt = (
SELECT MIN(B.Nmr)
FROM IDS AS B
WHERE B.Section = A.Section AND B.Nmr > A.Nmr
)
FROM IDS AS A
) AS D
WHERE nxt - cur > 1
ORDER BY Section, StartNmr
-----------------------
Section StartNmr EndNmr
-----------------------
CI 1 479
CW 1 94
-----------------------
Section StartNmr EndNmr
-----------------------
CI 1 479
CI 488 999
CW 1 94
CW 96 999
输出(无最大值):
CREATE TABLE [dbo].[Gaps] (
[Text] nvarchar(50) NOT NULL
);
INSERT [dbo].[Gaps] ([Text])
VALUES
('CI-480-1617'),
('CI-481-1617'),
('CI-482-1617'),
('CI-483-1617'),
('CI-484-1617'),
('CI-485-1617'),
('CI-486-1617'),
('CI-487-1617'),
('CW-095-1617');
WITH IDS (Section, Nmr) AS (
SELECT
SUBSTRING([Text], 1, CHARINDEX('-', [Text]) - 1),
CONVERT(int, SUBSTRING([Text], CHARINDEX('-', [Text]) + 1, CHARINDEX('-', [Text], CHARINDEX('|', [Text]))))
FROM Gaps
UNION ALL
SELECT
DISTINCT SUBSTRING([Text], 1, CHARINDEX('-', [Text]) - 1),
0
FROM Gaps
-- Uncomment next lines if you want to get the gap to some MAX value
--UNION ALL
--SELECT
-- DISTINCT SUBSTRING([Text], 1, CHARINDEX('-', [Text]) - 1),
-- 1000
--FROM Gaps
)
SELECT Section, StartNmr = cur + 1, EndNmr = nxt - 1
FROM (
SELECT
Section,
cur = Nmr,
nxt = (
SELECT MIN(B.Nmr)
FROM IDS AS B
WHERE B.Section = A.Section AND B.Nmr > A.Nmr
)
FROM IDS AS A
) AS D
WHERE nxt - cur > 1
ORDER BY Section, StartNmr
-----------------------
Section StartNmr EndNmr
-----------------------
CI 1 479
CW 1 94
-----------------------
Section StartNmr EndNmr
-----------------------
CI 1 479
CI 488 999
CW 1 94
CW 96 999
输出(最大值):
CREATE TABLE [dbo].[Gaps] (
[Text] nvarchar(50) NOT NULL
);
INSERT [dbo].[Gaps] ([Text])
VALUES
('CI-480-1617'),
('CI-481-1617'),
('CI-482-1617'),
('CI-483-1617'),
('CI-484-1617'),
('CI-485-1617'),
('CI-486-1617'),
('CI-487-1617'),
('CW-095-1617');
WITH IDS (Section, Nmr) AS (
SELECT
SUBSTRING([Text], 1, CHARINDEX('-', [Text]) - 1),
CONVERT(int, SUBSTRING([Text], CHARINDEX('-', [Text]) + 1, CHARINDEX('-', [Text], CHARINDEX('|', [Text]))))
FROM Gaps
UNION ALL
SELECT
DISTINCT SUBSTRING([Text], 1, CHARINDEX('-', [Text]) - 1),
0
FROM Gaps
-- Uncomment next lines if you want to get the gap to some MAX value
--UNION ALL
--SELECT
-- DISTINCT SUBSTRING([Text], 1, CHARINDEX('-', [Text]) - 1),
-- 1000
--FROM Gaps
)
SELECT Section, StartNmr = cur + 1, EndNmr = nxt - 1
FROM (
SELECT
Section,
cur = Nmr,
nxt = (
SELECT MIN(B.Nmr)
FROM IDS AS B
WHERE B.Section = A.Section AND B.Nmr > A.Nmr
)
FROM IDS AS A
) AS D
WHERE nxt - cur > 1
ORDER BY Section, StartNmr
-----------------------
Section StartNmr EndNmr
-----------------------
CI 1 479
CW 1 94
-----------------------
Section StartNmr EndNmr
-----------------------
CI 1 479
CI 488 999
CW 1 94
CW 96 999
理想情况下,您应该将序列号作为完全独立的数字列。如果你需要经常这样做,那么这是一个值得做的改变。你的桌子看起来怎么样?你的数据看起来怎么样?这里的差距是什么?中间数的差距,由第一个和最后一个组成部分划分吗?请举例说明缺口是什么样子的。