表1如下:
Col1
1
2
3
4
6
7
8
9
10
13
14
如上所示,col1具有值序列,但由于某种原因,用户未插入5,11等等。如何找出序列中的缺失值。这里的序列是1到14,缺失值是5,11。请帮帮我。
答案 0 :(得分:4)
正如在其他答案中所说,最好的选择是使用真实序列表进行连接。您可以使用递归CTE创建一个:
DECLARE @MaxNumber INT
SELECT @MaxNumber = MAX(Col1) FROM YourTable;
WITH CTE AS
(
SELECT 1 Col1
UNION ALL
SELECT Col1+1
FROM CTE
WHERE Col1+1 <= @MaxNumber
)
SELECT A.Col1
FROM CTE A
LEFT JOIN YourTable B
ON A.Col1 = B.Col1
WHERE B.Col1 IS NULL
OPTION(MAXRECURSION 0)
答案 1 :(得分:3)
这适用于数字0 - 2000,对于大数字,您只需要交叉加入原始结果集。
with temp as (
select distinct number
from master..spt_Values
where number between 0 and 2000
)
select * from
temp t
left join your_table y on y.col1 = t.number
where y.col1 is null
或者使用交叉连接
这将对数十亿显然较慢的
起作用 WITH
L0 AS(SELECT 1 AS c UNION ALL SELECT 1),
L1 AS(SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B),
L2 AS(SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B),
L3 AS(SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B),
L4 AS(SELECT 1 AS c FROM L3 AS A CROSS JOIN L3 AS B),
L5 AS(SELECT 1 AS c FROM L4 AS A CROSS JOIN L4 AS B),
Nums AS(SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS n FROM L5)
select * from
l5 t
left join your_table y on y.col1 = t.n
where y.col1 is null
答案 2 :(得分:0)
这似乎是
的重复SQL query to find Missing sequence numbers
有一些建议可行:
SELECT l.id + 1 as start
FROM Table1 as l
LEFT JOIN Table1 as r on l.id + 1 = r.id
WHERE r.id IS NULL
否则,您可以使用序列表在表上保持连接。从上面的问题,您可以查看http://www.projectdmx.com/tsql/tblnumbers.aspx以获得有关如何生成合适的序列表的一些想法,并且连接将类似于
SELECT #sequence.value
FROM #sequence
LEFT JOIN Table1 ON #sequence.value = Table1.value
WHERE Table1.value IS NULL
答案 3 :(得分:0)
侧注。递归CTE增加了与行数成线性关系的时间。使用计数表或交叉连接要好得多......
这样可行:
-- data table
CREATE TABLE #data (
value INT
)
INSERT #data VALUES (1)
INSERT #data VALUES (2)
INSERT #data VALUES (3)
INSERT #data VALUES (4)
INSERT #data VALUES (6)
INSERT #data VALUES (7)
INSERT #data VALUES (8)
INSERT #data VALUES (9)
INSERT #data VALUES (10)
INSERT #data VALUES (13)
INSERT #data VALUES (14)
-- normally i have a tally table already for stuff like this but I'll
-- create one temporary here.
CREATE TABLE #tmp_tally (
n INT
)
DECLARE @n INT
SET @n = 1
WHILE @n < 14
BEGIN
INSERT #tmp_tally VALUES (@n)
SET @n = @n + 1
END
SELECT
T.n,
CASE WHEN #data.value IS NULL THEN 'Missing' ELSE 'Not Missing' END
FROM
#tmp_tally T
LEFT JOIN #data ON
T.n = #data.value
WHERE
T.n <= (SELECT MAX(value) FROM #data) -- max of what you want to check against which is 14 in your example
DROP TABLE #data
DROP TABLE #tmp_tally
答案 4 :(得分:0)
试试这个:
declare @min int
declare @max int
select @min = min(field_ID), @max = max(field_ID) from [Table]
create table #tmp (Field_No int)
while @min <= @max
begin
if not exists (select * from [Table] where field_ID = @min)
insert into #tmp (seq_field) values (@min)
set @min = @min + 1
end
select * from #tmp
drop table #tmp
使用上述脚本,您将在&#34; ID &#34;来自#tmp table的列。
希望这会对你有所帮助!!
答案 5 :(得分:-1)
我会在同一个表中执行子查询,以查看当前数字1是否存在另一个数字,如果没有,则表示已跳过一个数字。你也可以做+1。
选择 nt.numb, 案件 (从表中选择COUNT(*),其中numb = nt.numb-1)= 0然后'跳过'ELSE'没有被跳过' 从 numbertable nt