2009-09-14 3 views
0

저는이 문제가 있습니다. 저는이를 해결할 수 없습니다. 나는 누락 된 숫자 간격을 얻을 수는 있지만, 나는 연속 시리즈에서 그걸 다시 모을 수는 없다.시리즈에서 연속 간격을 모두 생성하십시오.

따라서 [1000100110021003100510061008]으로 정의 된 시리즈가있는 경우 세 연속 시리즈 [1000100110021003] 및 [1005,1006]을 추출하고 싶습니다. 및 [1008]. 간단한 CTE를 사용하여 1003, 1005,1006 및 1008을 얻었으므로 간격의 끝과 시작을 얻을 수 있지만 지금은 무엇입니까?

|to |from | 
|1000 |1003 | 
|1005 |1006 | 
|1008 |1008 | 

누구나가 공유 할 스마트 솔루션을 가지고 : 결국

나는 다음과 같다 표를 줄까?

편집

:

WITH MissingNumbers (FromNumber, ToNumber) AS 
( 
SELECT 
    T1.TaxLabelNumber, 
    T2.TaxLabelNumber 
FROM TaxLabel T1 
JOIN TaxLabel T2 
    ON T1.TaxLabelId + 1 = T2.TaxLabelId 
WHERE T1.TaxLabelNumber <> T2.TaxLabelNumber - 1 
) 
SELECT * INTO #TempNumbers 
FROM MissingNumbers 

EDIT2 : 년 OFC 여기 은 (아마도 reduntant) CTE이다. 계획이 바뀌었기 때문에 더 이상 이런 종류의 해결책이 필요하지 않습니다. 모든 답장을 보내 주셔서 감사합니다! 매우 도움이 됨 : D

답변

0

쉬운 방법은 TaxLabelNumbers가있는 테이블을 사용하여 외부 조인을 할 수 있도록하는 것입니다.

CTE에서 그런 종류의 표를 만들 수도 있지만 그다지 효율적이지는 않습니다. 100 재귀에

with TaxLabelSeq(Number) as 
( 
    select @FromNumber as Number 
     union all 
    select Number + 1 
     from NumberSequence 
     where Number < @ToNumber 
) 

CTE 현명 기본값 당신은 100 개 이상의 번호가 필요한 경우이를 흔들 필요가 있도록 : 시도

select * from TaxLabelSeq option (MaxRecursion 4711) 
0

을이

SELECT SSTART.num series_start, MIN(SEND.num) series_end 
FROM #series SSTART, #series SEND 
WHERE 
     /* anything that does not have a predecessor is a START */ 
     SSTART.num - 1 NOT IN (SELECT num FROM #series) AND 
     /* anything that does not have a following entry is an END */ 
     SEND.num + 1 NOT IN (SELECT num FROM #series) AND 
     /* now join each START with every END above it */ 
     SEND.num >= SSTART.num 
     /* we group over each START, so we can get the corresponding END with MIN */ 
GROUP BY SSTART.num 
0
WITH data AS 
     (
     SELECT 1000 AS number 
     UNION ALL 
     SELECT 1001 
     UNION ALL 
     SELECT 1002 
     UNION ALL 
     SELECT 1003 
     UNION ALL 
     SELECT 1005 
     UNION ALL 
     SELECT 1006 
     UNION ALL 
     SELECT 1008 
     ), 
     rows AS 
     (
     SELECT q2.number AS nnumber, q.number AS number 
     FROM (
       SELECT number 
       FROM data di 
       WHERE NOT EXISTS 
         (
         SELECT NULL 
         FROM data dn 
         WHERE dn.number = di.number - 1 
         ) 
       ) q 
       OUTER APPLY 
       (
       SELECT TOP 1 number 
       FROM data dp 
       WHERE dp.number < q.number 
       ORDER BY 
         dp.number DESC 
       ) q2 
     UNION ALL 
     SELECT TOP 1 number, NULL 
     FROM data 
     ORDER BY 
       number DESC 
     ), 
     rns AS 
     (
     SELECT *, ROW_NUMBER() OVER (ORDER BY nnumber) AS rn 
     FROM rows 
     ) 
SELECT re.number, rb.nnumber 
FROM rns re 
JOIN rns rb 
ON  rb.rn = re.rn + 1 
관련 문제