2009-02-03 4 views
11

다른 테이블에 일치하는 레코드가없는 레코드를 찾기 위해 쿼리를 작성하려고합니다.SQL을 사용하여 일치하지 않는 레코드 찾기

예를 들어, 나는 누구의 구조 이런 식으로 뭔가를 보이는 두 개의 테이블이 있습니다

 
Table1 
    State | Product | Distributor | other fields 
    CA | P1  | A   | xxxx 
    OR | P1  | A   | xxxx 
    OR | P1  | B   | xxxx 
    OR | P1  | X   | xxxx 
    WA | P1  | X   | xxxx 
    VA | P2  | A   | xxxx 

Table2 
    State | Product | Version | other fields 
    CA | P1  | 1.0 | xxxx 
    OR | P1  | 1.5 | xxxx 
    WA | P1  | 1.0 | xxxx 
    VA | P2  | 1.2 | xxxx 

(. 주/제품/배포자가 함께 표시/제품에 대한 키를 형성 표 2의 키입니다)

배포자 X를 사용하지 않는 모든 주/제품/버전 조합을 찾고 싶습니다. (이 예제의 결과는 CA-P1-1.0 및 VA-P2-1.2입니다.)

에 대한 제안 사항 이 일을하는 쿼리?

+0

마지막 문장에 두 번째에서, 심지어이 쿼리에 관여 표 2 하는가? (아마 제품의 버전을 얻는 것을 제외하고). – Tundey

+0

나는 당신이 당신 자신의 질문에 대답했다고 생각합니다. Table2는 버전을 얻는 데 필요합니다. –

답변

24
SELECT 
    * 
FROM 
    Table2 T2 
WHERE 
    NOT EXISTS (SELECT * 
     FROM 
      Table1 T1 
     WHERE 
      T1.State = T2.State AND 
      T1.Product = T2.Product AND 
      T1.Distributor = 'X') 

이것은 ANSI와 호환되어야합니다.

+0

이것은 대부분의 SQL 시스템에서 작동합니다. EXCEPT는 어디서나 작동하지 않습니다 (작동하는 곳이 더 우아함에도 불구하고). –

+0

하위 쿼리에서 "SELECT * FROM"대신 "SELECT 1 FROM"을 사용하면 불필요한 테이블 검색을 방지 할 수 있습니다. 비록 DBMS가 "EXISTS"를 보았을 때 자신의 것으로 파악하기에 충분히 영리 할 것이라고 기대하지만. – Tomalak

+1

SQL Server MVP 동료와 함께 항상 이것을 가지고 있습니다 : *) 컴파일 타임에 *가 확장되고, bt가 간단하게 축소되지만 런타임은 아닙니다. 그는 한 번 기사를 보여 줬어. 나는 얼마 전 이삭 벤 간 (Itzak Ben-Gan)을 보았고 그는 *가 더 빠르다고 말했다. 선택은 당신의 것입니다 ... – gbn

1

이 표에서 선택 * 어디 있지의 상태 (표 1에서 상태를 선택 곳에 유통 = 'X')

아마 아닐 가장 영리하지만 그 작동합니다. T-SQL에서

+0

IN은 아닙니다. EXISTS만큼 좋으며 상태/제품상의 복합 키를 처리하지 않는다 – gbn

+1

또한 RDBMS에 의존하여'NOT IN'은'state'가 nullable 일 때 예상대로 동작하지 않습니다. –

8

: 필요

SELECT DISTINCT Table2.State, Table2.Product, Table2.Version 
FROM Table2 
    LEFT JOIN Table1 ON Table1.State = Table2.State AND Table1.Product = Table2.Product AND Table1.Distributor = 'X' 
WHERE Table1.Distributor IS NULL 

없음 하위 쿼리.

편집 : 주석에 표시된대로 DISTINCT는 필요하지 않습니다. 감사! 오라클에서

+0

나는 distinct를 사용하지 않겠지 만, 그렇지 않으면 이것이 당신이 원하는 것입니다. – HLGEM

+0

별개로 표시하면 쿼리의 효율성이 떨어지지만 효율성은 떨어집니다. 상대 테이블 행 수에 따라 다릅니다. distcnt는 하위 쿼리가 필요로하지 않는 집계도 강제 실행합니다. – gbn

+1

이 쿼리의 성능과 동작은 'Distributor'가 조인에 사용 된 인덱스로 덮여 있는지 여부에 따라 달라집니다 (그렇지 않은 경우 조회가 필요할 수도 있고 인덱스 작업이 클러스터형 인덱스 작업으로 변환되어야 할 수도 있음). 'Distributor '는 NULL 가능합니다 (일치하지 않는 행 이외에 값이없는 일치하는 행을 반환 할 수 있음). –

1
SELECT DISTINCT t2.State, t2.Product, t2.Version 
FROM table2 t2 
JOIN table1 t1 ON t1.State = t2.State AND t1.Product = t2.Product 
       AND t1.Distributor <> 'X' 
1

:

SELECT t2.State, t2.Product, t2.Version 
FROM Table2 t2, Table t1 
WHERE t1.State(+) = t2.State 
    AND t1.Product(+) = t2.Product 
    AND t1.Distributor(+) = :distributor 
    AND t1.State IS NULL 
관련 문제