在SQL Server中查找2个数字之间缺少的行

在SQL Server中查找2个数字之间缺少的行,sql,sql-server,Sql,Sql Server,我想在SQL Server中查找两个数字之间缺少的所有行 例如,我在SQL Server的一个表中有一个范围从100000到200000的[INVOICE_NO]列。100000到200000之间的每个数字都应该有一行。如何检查并查找表中缺少的发票号 我知道如何做,如果100000到200000之间的每个数字都存储在一个单独的表中,那么我可以只做而不做选择。。。但我不知道没有它怎么办。如评论所述,我会在这里使用理货表,而不是rCTE: DECLARE @Start int, @End int;

我想在SQL Server中查找两个数字之间缺少的所有行

例如,我在SQL Server的一个表中有一个范围从100000到200000的[INVOICE_NO]列。100000到200000之间的每个数字都应该有一行。如何检查并查找表中缺少的发票号


我知道如何做,如果100000到200000之间的每个数字都存储在一个单独的表中,那么我可以只做而不做选择。。。但我不知道没有它怎么办。

如评论所述,我会在这里使用理货表,而不是rCTE:

DECLARE @Start int, @End int;
SET @Start = 100000;
SET @End = 200000;

WITH N AS(
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) I
    FROM N N1, N N2, N N3, N N4, N N5, N N6) --1M rows should be enough
SELECT T.I AS MISSING_INVOICE_NO
FROM Tally T
     --LEFT JOIN YourTable YT ON T.I = YT.INVOICE_NO
WHERE T.I BETWEEN @Start AND @End
--AND YT.INVOICE_NO IS NULL
您需要注释掉并调整行以加入到表中

作为推理的证明,采用以下脚本:

然而,rCTE方法是:


这在时间上是一个很大的差异,因为理货解决方案的平均时间约为100ms,而rCTe在2到4秒之间。

如果你能处理范围,你可以通过以下方式获得所有间隙:

select (invoice_no + 1) as first_missing_invoice_no, 
       (next_invoice_no - 1) as last_missing_invoice_no,
       count(*) as num_missing
from (select i.*,
             lead(invoice_no) over (order by invoice_no) as next_invoice_no
      from invoices i
     ) i
where next_invoice_no <> invoice_no + 1;

如果范围满足您的需要,则可以将其应用于特定范围。

使用递归cte生成值100 000到200 000。外部连接。我建议使用理货台,而不是rCTE。生成100000次的rCTE可能很昂贵。rCTE在32768次迭代后达到最大值。您可以使用选项MAX RECURSION 0@SalmanA,这不是我的建议。显然我错过了0键。不管怎样,我证明了你也可以在我的答案中使用rCTE,但是它的速度与计分相比是可怕的。嗨,谢谢。只是尝试一下,但它似乎显示了该列中存在的数字,这些数字被左键连接起来了……我不知道@user316478的WHERE和YT.INVOICE_no是如何为空的。由于INVOICE\u NO的值为NULL,因此查询不可能返回INVOICE\u NO有值的行。您需要提供您的语句,因为您似乎做错了什么。表现出按预期工作。
CPU time = 78 ms,  elapsed time = 106 ms.
CPU time = 78 ms,  elapsed time = 95 ms.
CPU time = 62 ms,  elapsed time = 91 ms.
CPU time = 78 ms,  elapsed time = 105 ms.
CPU time = 2547 ms,  elapsed time = 3695 ms.
CPU time = 2250 ms,  elapsed time = 2500 ms.
CPU time = 1813 ms,  elapsed time = 1930 ms.
CPU time = 2750 ms,  elapsed time = 3220 ms.
select (invoice_no + 1) as first_missing_invoice_no, 
       (next_invoice_no - 1) as last_missing_invoice_no,
       count(*) as num_missing
from (select i.*,
             lead(invoice_no) over (order by invoice_no) as next_invoice_no
      from invoices i
     ) i
where next_invoice_no <> invoice_no + 1;