2014-11-27 8 views
0

Я должен определить недостающие записи из приведенного ниже примера.Поиск недостающих последовательностей по категориям

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 не существует, поскольку они потенциально не были вставлены еще.

+0

номер партий идет выше делает 6? –

+0

мы можем увидеть номер партии «7» для CAT1 ... @NeerajPrasadSharma – mlwn

+0

@Neeraj Prasad Sharma no it not ...... –

ответ

1

Вы можете создать временный результирующий набор со всей возможной периодичностью до максимального номера партии для каждой категории, чем выбрать партию no, которые недоступны.

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 
0

Этот номер использует Tally Table. Для справки: http://www.sqlservercentral.com/articles/T-SQL/62867/

SAMPLE DATA

create table MyTable(
    Category varchar(10), 
    BatchNo int, 
    TransactionNo int 
) 
insert into MyTable 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, 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); 

РЕШЕНИЕ

with e1(n) as (
    select 1 union all select 1 union all select 1 union all 
    select 1 union all select 1 union all select 1 union all 
    select 1 union all select 1 union all select 1 union all select 1 
), --10e+1 or 10 rows 
e2(n) as (select 1 from e1 a, e1 b), --10e+2 or 100 rows 
e4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows 
tally(n) as(
    select 
     top (select top 1 BatchNo from MyTable order by BatchNo desc) 
     row_number() over(order by (select null)) 
    from e4 
) 
select 
    c.Category, 
    t.n 
from tally t 
cross join(
    select 
     Category, 
     max(BatchNo) as MaxBatchNo 
    from MyTable 
    group by Category 
)c 
left join MyTable m 
    on m.BatchNo = t.n 
    and m.Category = c.Category 
where 
    m.Category is null 
    and t.n < c.MaxBatchNo 
order by 
    c.Category, 
    t.n 
0

Лучше создать таблицу проекционного и использовать стандартные left join, чтобы найти пробелы:

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; 

Конечно, в реальном ife вам может потребоваться более 1000 строк, поэтому соответствующим образом отрегулируйте их.

0
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 
0

без использования цикла или выборки вы можете использовать этот: (# Категория - это мой эквавалент имени вашей таблицы). (Performance идеально)

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 
0
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) 
Смежные вопросы