2014-11-27 4 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 

나는 나는 그들이 잠재적으로 아직 삽입되지 않은으로 CAT1 8CAT2 7가 아니라는 것을 알 필요가 없습니다

Category BatchNo 
+++++++++++++++++++ 
CAT1   4 
CAT1   6 
CAT2   2 
CAT2   5 

아래로없는 기록을 확인하는 스크립트가 필요합니다.

+0

배치 번호 6 위의 이동 도다 (성능이 최적입니다)? –

+0

우리는 CAT1에 대한 "7"배치 번호를 볼 수 있습니다. @NeerajPrasadSharma – mlwn

+0

@Neeraj Prasad Sharma 아니요 ...... –

답변

1

당신은 사용할 수 없습니다 어떤 선택 배치보다는 각 카테고리에는 최대 최대 배치 번호에 대한 모든 가능한 배치와 설정되지 임시 결과를 만들 수 있습니다.

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을 사용합니다. 참고 :

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; 

: http://www.sqlservercentral.com/articles/T-SQL/62867/

샘플 데이터

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를 사용하는 것이 좋습니다 물론, 리얼 리 ~ 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
사용주기없이

또는 당신이 하나를 사용할 수 있습니다 가져 오기 : (#Category은 테이블 이름의 내 eqvivalent입니다).

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)