Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 按类别查找缺失序列_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 按类别查找缺失序列

Sql 按类别查找缺失序列,sql,sql-server,tsql,Sql,Sql Server,Tsql,我必须从下面的示例中识别丢失的记录 Category BatchNo TransactionNo +++++++++++++++++++++++++++++++++ CAT1 1 1 CAT1 1 2 CAT1 2 3 CAT1 2 4 CAT1 2 5 CAT1 3 6 CAT1 3 7 CAT1

我必须从下面的示例中识别丢失的记录

Category    BatchNo TransactionNo
+++++++++++++++++++++++++++++++++
CAT1           1    1
CAT1           1    2
CAT1           2    3
CAT1           2    4
CAT1           2    5
CAT1           3    6
CAT1           3    7
CAT1           3    8
CAT1           5    12
CAT1           5    13
CAT1           5    14
CAT1           5    15
CAT1           7    18
CAT2           1    1
CAT2           1    2
CAT2           3    6
CAT2           3    7
CAT2           3    8
CAT2           3    9
CAT2           4    10
CAT2           4    11
CAT2           4    12
CAT2           6    14
我需要一个脚本,将确定丢失的记录如下

Category    BatchNo
+++++++++++++++++++
CAT1         4
CAT1         6
CAT2         2
CAT2         5
我不需要知道CAT1 8和CAT2 7不存在,因为它们可能还没有插入。

这一个使用理货表。供参考:

样本数据

解决方案
最好创建一个投影表,并使用标准的左联接查找间隙:

declare @Sequencer table (
    Id int primary key
);

insert into @Sequencer (Id)
select top (1000) row_number() over(order by (select null)) from master.dbo.spt_values;

select *
from @Sequencer s
    inner join (
        select Category, max(BatchNo) as [Size] from dbo.Table group by Category
    ) cat on cat.Size > s.Id
    left join (
        select distinct Category, BatchNo from dbo.Table
    ) t on t.Category = cat.Category and t.BatchNo = s.Id
where t.BatchNo is null;

当然,在现实生活中,您可能需要1000多行,因此请相应地进行调整。

除了选择不可用的批次号之外,您还可以为每个类别创建临时结果集,其中包含所有可能的批次号,最大批次号

WITH Numbers AS (
    SELECT MAX(BatchNo) AS Number
    FROM #MyTable
  UNION ALL
    SELECT Number - 1
    FROM Numbers
    WHERE Number > 1
)
,CategorySizes AS (
    SELECT Category
          ,MIN(BatchNo) AS StartBatch
          ,MAX(BatchNo) AS EndBatch
    FROM #MyTable
    GROUP BY Category
)
,PossibleBatches AS (
    SELECT Category
          ,Numbers.Number AS BatchNo
    FROM CategorySizes
         CROSS JOIN Numbers
    WHERE Numbers.Number BETWEEN CategorySizes.StartBatch AND CategorySizes.EndBatch                
)
,MissingBatches AS (
    SELECT PossibleBatches.Category
          ,PossibleBatches.BatchNo
    FROM PossibleBatches
         LEFT JOIN #MyTable
            ON #MyTable.Category = PossibleBatches.Category
               AND #MyTable.BatchNo = PossibleBatches.BatchNo
    WHERE #MyTable.BatchNo IS NULL
)
SELECT *
FROM MissingBatches
create table TEMP(
        Category varchar(10),
        BatchNo int,
        TransactionNo int
    )
    insert into TEMP values
    ('CAT1', 1, 1),
    ('CAT1', 1, 2),
    ('CAT1', 2, 3),
    ('CAT1', 2, 4),
    ('CAT1', 2, 5),
    ('CAT1', 3, 6),
    ('CAT1', 3, 7),
    ('CAT1', 3, 8),
    ('CAT1', 5, 9),
    ('CAT1', 7, 10),
    ('CAT2', 1, 1),
    ('CAT2', 1, 2),
    ('CAT2', 3, 3),
    ('CAT2', 4, 4),
    ('CAT2', 4, 5),
    ('CAT2', 4, 6),
    ('CAT2', 6, 7);


    WITH BatchNo (BatchID,Category,MaxBatch) AS (
      SELECT 1, Category, MAX(BatchNo) AS MaxBatch  FROM TEMP GROUP BY Category
      UNION ALL
      SELECT BatchID + 1, Category, MaxBatch FROM BatchNo
      WHERE BatchID < MaxBatch
    )

    SELECT 
        BatchNo.Category,
        BatchNo.BatchID
    FROM 
        BatchNo
    WHERE 
        BatchID NOT IN (SELECT BatchNo FROM TEMP WHERE Category = BatchNo.Category)
    ORDER BY
        BatchNo.Category,
        BatchNo.BatchID


    DROP TABLE TEMP

如果不使用cycle或fetch,您可以使用这个:Category是表名的等价物。表演是完美的

DECLARE @t TABLE (RN INT IDENTITY,Category VARCHAR(255), BatchNo INT)

INSERT INTO @t
SELECT DISTINCT Category, BatchNo
FROM #Category

SELECT a.Category,a.BatchNo+1 AS BatchNo 
FROM @t a
CROSS APPLY (SELECT * FROM @t b 
                      WHERE a.RN+1 = b.RN AND 
                            a.Category = b.Category AND 
                            a.BatchNo+1 != b.BatchNo) x

批号不超过6?我们可以看到CAT1的批号为7@NeerajPrasadSharma@NeerajPrasad Sharma不,不是……那么最大批次数是否一直在变化?如果第2类批次号变为8,那么第1类批次号也应该变为第8批?@Neeraj Prasad Sharma不,这是我仅有的数据,不会改变
create table TEMP(
        Category varchar(10),
        BatchNo int,
        TransactionNo int
    )
    insert into TEMP values
    ('CAT1', 1, 1),
    ('CAT1', 1, 2),
    ('CAT1', 2, 3),
    ('CAT1', 2, 4),
    ('CAT1', 2, 5),
    ('CAT1', 3, 6),
    ('CAT1', 3, 7),
    ('CAT1', 3, 8),
    ('CAT1', 5, 9),
    ('CAT1', 7, 10),
    ('CAT2', 1, 1),
    ('CAT2', 1, 2),
    ('CAT2', 3, 3),
    ('CAT2', 4, 4),
    ('CAT2', 4, 5),
    ('CAT2', 4, 6),
    ('CAT2', 6, 7);


    WITH BatchNo (BatchID,Category,MaxBatch) AS (
      SELECT 1, Category, MAX(BatchNo) AS MaxBatch  FROM TEMP GROUP BY Category
      UNION ALL
      SELECT BatchID + 1, Category, MaxBatch FROM BatchNo
      WHERE BatchID < MaxBatch
    )

    SELECT 
        BatchNo.Category,
        BatchNo.BatchID
    FROM 
        BatchNo
    WHERE 
        BatchID NOT IN (SELECT BatchNo FROM TEMP WHERE Category = BatchNo.Category)
    ORDER BY
        BatchNo.Category,
        BatchNo.BatchID


    DROP TABLE TEMP
DECLARE @t TABLE (RN INT IDENTITY,Category VARCHAR(255), BatchNo INT)

INSERT INTO @t
SELECT DISTINCT Category, BatchNo
FROM #Category

SELECT a.Category,a.BatchNo+1 AS BatchNo 
FROM @t a
CROSS APPLY (SELECT * FROM @t b 
                      WHERE a.RN+1 = b.RN AND 
                            a.Category = b.Category AND 
                            a.BatchNo+1 != b.BatchNo) x
create table #cat(
        Category varchar(10),
        BatchNo int,
        TransactionNo int
    )
insert into #cat values
    ('CAT1', 1, 1),
    ('CAT1', 1, 2),
    ('CAT1', 2, 3),
    ('CAT1', 2, 4),
    ('CAT1', 2, 5),
    ('CAT1', 3, 6),
    ('CAT1', 3, 7),
    ('CAT1', 3, 8),
    ('CAT1', 5, 9),
    ('CAT1', 7, 10),
    ('CAT2', 1, 1),
    ('CAT2', 1, 2),
    ('CAT2', 3, 3),
    ('CAT2', 4, 4),
    ('CAT2', 4, 5),
    ('CAT2', 4, 6),
    ('CAT2', 6, 7);


SELECT DISTINCT C.Category, C.BatchNo + 1
FROM #cat c
OUTER APPLY
    (
        SELECT *
        FROM #cat c1
        WHERE C1.BatchNo = C.BatchNo + 1 AND C1.Category = C.Category
) C2
WHERE C2.BatchNo IS NULL 
      AND 
      C.BatchNo <> (SELECT MAX(BatchNo) FROM #cat C3 WHERE c3.Category = c.Category)