문제

우리의 직장은 아카이브 등을 수동으로 유지하는 대신 모든 문서를 스캔하기 시작했습니다.

평균적으로 우리는 시간당 1,000 개의 문서를 스캔하고 있습니다 (이것은 하루에 약 30 회 발생합니다).

우리가 1,000 개의 문서를 스캔 할 때마다 OCR에 소량의 오류 / 경고를받습니다.

는 가장 낮고 가장 높은 순서 번호를 변수에 제공하고 SQL Server를 얻을 수 있으며 가장 낮은 순서 번호 사이에 테이블에없는 모든 누락 된 순서 번호 목록을 출력 할 수 있습니까?

예 :

OCROrderNo
---------------
9001
9002
9006
9007
9008
9009
.

가장 낮은 번호 9001, 가장 높은 번호 9009

MissingOrderNos
--------------------
9003
9094
9005
.

추가 정보

답변에 따라, 이것이 내가 시도하고있는 것 :

DECLARE @Start INT = 1497389
        , @End INT = 1498264

SELECT @Start + N - 1
FROM   dbo.Numbers
WHERE  N <= ( 1 + @End - @Start )
EXCEPT
SELECT [ORDERNUMBER]
FROM   [dwdata].[dbo].[ORDERS]
ORDER BY [ORDERNUMBER] DESC
.

결과 :

msg 207, 레벨 16, 상태 1, 라인 10
열 이름이 'ordernumber'가 잘못되었습니다.

msg 104, 레벨 16, 상태 1, 라인 10
명령문에 연합, 교차 또는 이외 연산자가 포함 된 경우 항목별로 주문 목록에 표시되어야합니다.

도움이 되었습니까?

해결책

먼저 관심있는 최대 범위보다 큰 보조 숫자 테이블을 만듭니다.

CREATE TABLE dbo.Numbers
(
N INT primary key
);   


WITH E00(N) AS (SELECT 1 UNION ALL SELECT 1),
    E02(N) AS (SELECT 1 FROM E00 a, E00 b),
    E04(N) AS (SELECT 1 FROM E02 a, E02 b),
    E08(N) AS (SELECT 1 FROM E04 a, E04 b),
    E16(N) AS (SELECT 1 FROM E08 a, E08 b),
    E32(N) AS (SELECT 1 FROM E16 a, E16 b),
cteTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY N) FROM E32)
INSERT 
INTO  dbo.Numbers
SELECT TOP(100000) N
FROM cteTally
OPTION (MAXDOP 1);
.

다음 쿼리는 간단합니다

DECLARE @Start INT = 9001
        , @End INT = 9009

SELECT @Start + N - 1 AS ORDERNUMBER
FROM   dbo.Numbers
WHERE  N <= ( 1 + @End - @Start )
EXCEPT
SELECT [ORDERNUMBER]
FROM   [dwdata].[dbo].[ORDERS]
ORDER BY [ORDERNUMBER] DESC
.

다른 팁

여기에 시작할 것이 있습니다.요청한 것과 마찬가지로 누락 된 모든 ID가있는 목록을 반환합니다.

다른 테이블이 필요 없습니다.

CREATE TABLE Numbers(n INT )
INSERT INTO Numbers SELECT 9001
INSERT INTO Numbers SELECT 9002
INSERT INTO Numbers SELECT 9006
INSERT INTO Numbers SELECT 9007
INSERT INTO Numbers SELECT 9008
INSERT INTO Numbers SELECT 9009

SELECT * FROM Numbers ORDER BY n

;WITH i AS
(
    SELECT LAG(n) OVER (ORDER BY n) AS PrevN
    ,n
    FROM Numbers
),
MissingList AS 
(
SELECT i.PrevN+1 AS MissingN, i.n-1 AS EndNum FROM i WHERE i.PrevN+1 <= i.n-1
    UNION ALL
    SELECT MissingN+1, EndNum FROM MissingList WHERE MissingN+1<=EndNum
)
SELECT MissingN AS MissingOrderNos FROM MissingList
WHERE MissingN BETWEEN 9001 AND 9009
ORDER BY MissingN
OPTION (maxrecursion 10000)
.

마지막 SQL의 결과는 다음과 같습니다.

MissingOrderNos
---------------
9003
9004
9005
.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 dba.stackexchange
scroll top