2009-04-07 13 views
3

나는 ID의 테이블을 가지고 배치SQL의 그룹 내에서 누락 된 값을 찾는 방법은 무엇입니까?

CREATE TABLE #MissingSequence (ID INT NOT NULL, Position INT NOT NULL) 
INSERT INTO #MissingSequence (ID,Position) 
SELECT 36,1 
UNION ALL SELECT 36,2 
UNION ALL SELECT 36,3 
UNION ALL SELECT 36,4 
UNION ALL SELECT 36,5 
UNION ALL SELECT 36,6 
UNION ALL SELECT 44,1 
UNION ALL SELECT 44,3 
UNION ALL SELECT 44,4 
UNION ALL SELECT 44,5 
UNION ALL SELECT 44,6 

내가 찾으려고 노력하고이 경우 ID에 의한 위치 순서에있는 휴식 44,1와 44,3

사이의 틈이있는 경우입니다

SELECT l.ID 
    ,Start_Position = MIN(l.Position) + 1 
    ,Stop_Position = MIN(fr.Position) - 1 
FROM #MissingSequence l 
LEFT JOIN #MissingSequence r 
    ON l.Position = r.Position - 1 
LEFT JOIN #MissingSequence fr 
    ON l.Position < fr.Position 
WHERE r.Position IS NULL 
    AND fr.Position IS NOT NULL 
GROUP BY l.ID 

을하지만, 여러 ID 값이있는 경우 작동하지 않습니다 :

나는 함께 분석 관리했습니다. 하나의 ID, 44 만 있으면 작동합니다.

생각, 의견, 제안?

감사합니다.

+0

무엇 출력 당신이 좋아하는 것이 보다? 최대 허용 게재 순위 값이 있습니까? – tpdi

+0

최대 위치 수 없음 ... 12K ID 레코드, 위치는 3 ~ x –

+0

인 @Christopher에 대한 약 12k ID 레코드가 포함 된 전체 테이블에 내 솔루션에 문제가 있습니까? –

답변

7

왼쪽 자체 조인이 좋은 본능이었다 사용할 수 있지만, 나는 집계가 그것을 잘라하려고 생각하지 않는다, 확실히 당신에게 필요한 것 자체 조인에 일치 ID 절을 포함 시키십시오. 여기

을 사용하여 (ANSI 호환) 버전의 널 왼쪽 조인 그들 사이에 아무것도 없다 최고의 행과 아래 행을 선택하고 확인, 아이디어를 :

SELECT 
    above.ID AS ID, below.Position+1 AS Start_Position, above.Position-1 AS End_Position 
FROM MissingSequence AS above 
JOIN MissingSequence AS below 
    ON below.ID=above.ID AND below.Position<above.Position-1 
LEFT JOIN MissingSequence AS inbetween 
    ON inbetween.ID=below.ID AND inbetween.Position BETWEEN below.Position+1 AND above.Position-1 
WHERE inbetween.ID IS NULL; 

+----+----------------+--------------+ 
| ID | Start_Position | End_Position | 
+----+----------------+--------------+ 
| 44 |    2 |   2 | 
+----+----------------+--------------+ 
+0

나는 이것에 관한 것 같아 ... HAVING은 짜증나지만, 내가 생각해 낸 것보다 낫다. +1 [x] –

+0

오! 물론, 당신은 도움없이 그것을 할 수 있습니다. 위 쿼리를 업데이트했습니다. 조금 더 잘 수행해야합니다. – bobince

+0

정말 대단 했어! –

2

이 쿼리는 유용함을 알기 위해 전표를 찾습니다. 당신은 SQL 2005에있는 경우, 당신은 CTE

SELECT ID, Position + 1 
FROM #MissingSequence t1 
WHERE (Position + 1) NOT IN (SELECT Position FROM #MissingSequence t2 WHERE t1.ID = t2.ID) 
AND Position <> (SELECT MAX(Position) FROM #MissingSequence t2 WHERE t1.ID = t2.ID) 
+0

이것은 누락 된 단 하나의 위치 값만 발견 할 수 있습니까? – bobince

+0

아, 괜찮아, 괜찮아, –

0
create database testing 
use testing; 
create table sequence (
    id int not null primary key 
); 

insert into sequence(id) values 
    (1), (2), (3), (4), (6), (7), (8), (9), 
    (10), (15), (16), (17), (18), (19), (20); 

select * from sequence 

Create PROCEDURE test_proce(@mode varchar(50)) 
AS 
BEGIN 
    declare @se int; 
    set @se=0; 
    set @se=(
     select top 1 t.id + 1 
     from sequence t 
     left join sequence x on x.id = t.id + 1 
     where x.id is null 
     order by t.id 
    ); 
    select * from sequence where id<@se; 
END 

exec test_proce 'mode'