54

という名前の列がありますsequence。この列のデータは、1、2、3、4、5、7、9、10、15のようになります。

テーブルから欠落しているシーケンス番号を見つける必要があります。どのSQLクエリが私のテーブルから欠落しているシーケンス番号を見つけますか?私は次のような結果を期待しています

Missing numbers
---------------
6  
8  
11  
12  
13  
14  

私は1つのテーブルのみを使用しています。以下のクエリを試しましたが、希望する結果が得られません。

select de.sequence + 1 as sequence from dataentry as de 
left outer join dataentry as de1 on de.sequence + 1 = de1.sequence
where de1.sequence is null  order by sequence asc;
4

16 に答える 16

40

次のようなものはどうですか:

  select (select isnull(max(val)+1,1) from mydata where val < md.val) as [from],
     md.val - 1 as [to]
  from mydata md
  where md.val != 1 and not exists (
        select 1 from mydata md2 where md2.val = md.val - 1)

要約された結果を与える:

from        to
----------- -----------
6           6
8           8
11          14
于 2009-06-29T09:35:34.703 に答える
23

これは非常に古い投稿であることは知っていますが、簡単に見つけられるように、ここで見つけたこのソリューションを追加したかったのです。

WITH Missing (missnum, maxid)
AS
(
 SELECT 1 AS missnum, (select max(id) from @TT)
 UNION ALL
 SELECT missnum + 1, maxid FROM Missing
 WHERE missnum < maxid
)
SELECT missnum
FROM Missing
LEFT OUTER JOIN @TT tt on tt.id = Missing.missnum
WHERE tt.id is NULL
OPTION (MAXRECURSION 0); 
于 2011-12-09T20:03:14.033 に答える
13

これを試してください:

declare @min int
declare @max int

select @min = min(seq_field), @max = max(seq_field) from [Table]

create table #tmp (Field_No int)
while @min <= @max
begin
   if not exists (select * from [Table] where seq_field = @min)
      insert into #tmp (Field_No) values (@min)
   set @min = @min + 1
end
select * from #tmp
drop table #tmp
于 2009-06-29T09:33:43.990 に答える
11

最良の解決策は、シーケンスで一時テーブルを使用することです。そのようなテーブルを作成すると仮定すると、NULL チェックを使用した LEFT JOIN が機能するはずです。

SELECT      #sequence.value
FROM        #sequence
LEFT JOIN   MyTable ON #sequence.value = MyTable.value
WHERE       MyTable.value IS NULL

ただし、この操作を頻繁に繰り返す必要がある場合 (データベース内の 1 つのシーケンスよりも多く)、「静的データ」テーブルを作成し、必要なすべてのテーブルの MAX(値) にデータを入力するスクリプトを作成します。 .

于 2009-06-29T09:54:53.603 に答える
3
SELECT CASE WHEN MAX(column_name) = COUNT(*)
THEN CAST(NULL AS INTEGER)
-- THEN MAX(column_name) + 1 as other option
WHEN MIN(column_name) > 1
THEN 1
WHEN MAX(column_name) <> COUNT(*)
THEN (SELECT MIN(column_name)+1
FROM table_name
WHERE (column_name+ 1)
NOT IN (SELECT column_name FROM table_name))
ELSE NULL END
FROM table_name;
于 2012-02-22T14:26:58.463 に答える
2

以下は、指定された日付範囲の欠落している連番を返すストアド プロシージャを作成するスクリプトです。

CREATE PROCEDURE dbo.ddc_RolledBackOrders 
-- Add the parameters for the stored procedure here
@StartDate DATETIME ,
@EndDate DATETIME
AS 
    BEGIN

    SET NOCOUNT ON;

    DECLARE @Min BIGINT
    DECLARE @Max BIGINT
    DECLARE @i BIGINT

    IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL 
        BEGIN
            DROP TABLE #TempTable
        END

    CREATE TABLE #TempTable
        (
          TempOrderNumber BIGINT
        )

    SELECT  @Min = ( SELECT MIN(ordernumber)
                     FROM   dbo.Orders WITH ( NOLOCK )
                     WHERE OrderDate BETWEEN @StartDate AND @EndDate)
    SELECT  @Max = ( SELECT MAX(ordernumber)
                     FROM   dbo.Orders WITH ( NOLOCK )
                     WHERE OrderDate BETWEEN @StartDate AND @EndDate)
    SELECT  @i = @Min

    WHILE @i <= @Max 
        BEGIN
            INSERT  INTO #TempTable
                    SELECT  @i

            SELECT  @i = @i + 1

        END

    SELECT  TempOrderNumber
    FROM    #TempTable
            LEFT JOIN dbo.orders o WITH ( NOLOCK ) ON tempordernumber = o.OrderNumber
    WHERE   o.OrderNumber IS NULL

END

行く

于 2013-02-01T13:44:28.887 に答える
1

与えられたすべてのソリューションが複雑すぎませんか?これはもっと簡単ではないでしょうか:

SELECT  *
FROM    (SELECT  row_number() over(order by number) as N from master..spt_values) t
where   N not in (select 1 as sequence union  
        select 2 union 
        select 3 union 
        select 4 union 
        select 5 union 
        select 7 union 
        select 10 union 
        select 15
        )
于 2009-06-29T09:45:33.747 に答える
0

CTEのようなものを使用して解決し、完全なシーケンスを生成することもできます。

テーブルの作成#tmp(sequence int)

#tmp(sequence)値に挿入(1)
#tmp(sequence)値に挿入(2)
#tmp(sequence)値に挿入(3)
#tmp(sequence)値に挿入(5)
#tmp(sequence)値に挿入(6)
#tmp(sequence)値に挿入(8)
#tmp(sequence)値に挿入(10)
#tmp(sequence)値に挿入(11)
#tmp(sequence)値に挿入(14)

    DECLARE @max INT
    SELECT @max = max(sequence) from #tmp;

    with full_sequence
    (
        Sequence
    )
    as
    (
        SELECT 1 Sequence

        UNION ALL

        SELECT Sequence + 1
        FROM full_sequence
        WHERE Sequence < @max
    )

    SELECT
        full_sequence.sequence
    FROM
        full_sequence
    LEFT JOIN
        #tmp
    ON
        full_sequence.sequence = #tmp.sequence
    WHERE
        #tmp.sequence IS NULL

うーん-何らかの理由でここでフォーマットが機能していませんか?誰かが問題を見ることができますか?

于 2009-06-29T09:44:58.193 に答える
0
DECLARE @TempSujith TABLE
(MissingId int)

Declare @Id Int
DECLARE @mycur CURSOR
SET @mycur = CURSOR FOR Select  Id From tbl_Table

OPEN @mycur

FETCH NEXT FROM @mycur INTO @Id
Declare @index int
Set @index = 1
WHILE @@FETCH_STATUS = 0
BEGIN
    if (@index < @Id)
    begin
        while @index < @Id
        begin
            insert into @TempSujith values (@index)
            set @index = @index + 1
        end
    end
    set @index = @index + 1
FETCH NEXT FROM @mycur INTO @Id
END
Select Id from tbl_Table
select MissingId from @TempSujith
于 2012-01-11T05:57:27.263 に答える
0

便利な集計表を作成します:

-- can go up to 4 million or 2^22
select top 100000 identity(int, 1, 1) Id
into Tally
from master..spt_values
cross join master..spt_values

インデックスを作成するか、その単一の列を PK にします。次に、EXCEPT を使用して不足している番号を取得します。

select Id from Tally where Id <= (select max(Id) from TestTable)
except
select Id from TestTable
于 2014-08-01T03:55:22.780 に答える