2010-02-11 4 views
8

작동해야하는 쿼리를 가져 오는 데 문제가 있습니다. 그것은 형태mysql SELECT NOT IN() - 분리 세트?

SELECT DISTINCT a, b, c FROM t1 WHERE NOT IN (SELECT DISTINCT a,b,c FROM t2) AS alias 

에있어하지만 MySQL은 초크 여기서 "IN ("가 시작됩니다.합니까 MySQL의 지원이 구문?, 나는이 결과를 얻기에 관하여 갈 수 있습니까? 나는 (A, B의 고유 한 튜플을 찾으려하지 않는 경우 , c)는 표 1에 표 2에 없습니다.

답변

12

당신은 존재하지 않아야합니다 :

SELECT DISTINCT a, b, c FROM t1 WHERE NOT EXISTS (SELECT NULL FROM t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c) 

하나의 키만 검사하더라도 NOT IN을 사용하는 것이 가장 좋은 방법은 아닙니다. 그 이유는 NOT EXISTS를 사용하면 DBMS는 필요한 열에 대한 인덱스가 존재하는 경우에만 인덱스를 확인해야하며, NOT IN은 실제 데이터를 읽고 나중에 확인해야하는 전체 결과 집합을 만들어야합니다. .

LEFT JOIN을 사용하여 NULL을 확인하는 것은 좋지 않은 생각입니다. 쿼리가 전체 조인을 수행하고 두 테이블을 모두 읽고 이후에 많은 양을 버려야하기 때문에 테이블이 클 때 고통스럽게 느려집니다. 그것. 또한 열에서 NULL 값 확인을 허용하면 false positive를보고합니다.

+0

그거 알아? 나는이 쿼리를 실행했고, 오랜 시간 (10 분 이상) 걸려서 죽였다. 그런 다음 두 테이블에 대한 임시 테이블을 설정하고 다른 정보를 삽입했습니다. 그런 다음 임시 테이블에 대해 쿼리를 실행했습니다. 1 분 4 초 걸렸습니다. 왜 mysql이이 쿼리를 최적화 할 수 없습니까? – user151841

+1

솔직히 말해서, mysql은 다소 어리 석고 느린 점도 있습니다. 오라클, MS SQL, PostgreSQL은 많은 점에서 훨씬 뛰어납니다. 물론 테이블의 열에 인덱스를 추가하면 더 빨리 수행 할 수 있습니다. 색인을 매번 업데이트해야하기 때문에 삽입 시간이 소요되지만, 각 작업을 몇 번이나 수행해야하는지, 시간이 더 중요한지는 중요합니다. – wich

0

내가 아는 한, NOT IN은 한 번에 한 필드에만 사용할 수 있습니다. 필드는 "WHERE" 와 "NOT IN"

(편집 : 해당 없음이 존재 사용해보십시오 :.

SELECT a, b, c 
FROM t1 
WHERE NOT EXISTS 
    (SELECT * 
    FROM t2 
    WHERE t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c) 

또한 a, b 및 c가 동일한 경우 내부 조인은 DISTINCT가 아닌 모든 튜플을 제공해야하며 WHERE IS NULL 절이있는 LEFT JOIN은 아래에 언급 된 Charles와 같이 DISTINCT를 제공해야합니다.

+0

http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html 성령 하나님에서

, 즉 악몽 쿼리를 만들 것입니다. 나는 다른 두 값의 값에 따라 a, b 또는 c 값만 신경 씁니다! – user151841

+0

조인 사용은 어떻습니까? 모든 3 개의 필드에서 내부 조인은 모든 고유하지 않은 튜플을 반환해야합니다. – froadie

+0

또는 사용 방법은 있습니까? 존재하지 않는 t1에서 a, b, c를 선택하십시오 (SELECT * FROM t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c). 이것이 정확하게 맞는지 확실하지 않다. 나는 많은 경험을하지 못했다. – froadie

0

DISTINCT (T1)를 선택한다. * T1에서 T2 LEFT부터는 가입 (T1.A = T2.A AND T1.B = t2.b AND t1.c = t2.c) T2.A가 NULL WHERE

+0

테이블이 커서 왼쪽으로 조인하면 고통스럽게 느려진다. 이것은 매우 나쁜 생각이다. 당신은 일을 많이하고, 두 테이블 모두를 읽고 왼쪽 조인 결과 세트를 만드는 등 불필요합니다. – wich

+0

실제로. 성능이 현명하지 않습니다. – Charles

-1

WHERE 절 다음에 열 목록을 추가하고 별칭을 제거해야합니다.

나는 이것을 비슷한 테이블과 함께 시험해 보았습니다. MySQL의 world데시벨 사용

SELECT DISTINCT a, b, c 
FROM t1 WHERE (a,b,c) 
NOT IN (SELECT DISTINCT a,b,c FROM t2) 

:

-- dont include city 1, 2 
SELECT DISTINCT id, name FROM city 
WHERE (id, name) 
NOT IN (SELECT id, name FROM city WHERE ID IN (1,2)) 
+0

NOT EXISTS를 사용하는 것이 더 좋을 것입니다. NOT IN은 NOT EXISTS를 사용할 때 전체 테이블을 읽음으로써 하위 쿼리에 대한 결과 집합을 강제로 생성하지 않습니다. 하위 쿼리에 대해 결과 집합을 만들 필요가 없으며 열 NOT EXISTS는 색인 만 읽습니다. – wich

+0

정말이에요? 열이 인덱싱되지 않으면 NOT EXISTS가 느리게 NOT IN이됩니다. – Yada

0

글쎄, 나는 모든 위대한 조언 다른 사람에도 불구하고, 내 자신의 질문에 대답 준거야.

다음은 올바른 작업을 수행하기위한 구문입니다. 하지 "어떻게 특정 결과 집합을받을 수 있나요" "어떻게 SQL에서이 생각을 표현 않는다"

SELECT DISTINCT a, b, c FROM t1 WHERE (a,b,c) NOT IN (SELECT DISTINCT a,b,c FROM t2) 

그것의 효율성에 대한 신뢰도를 보장 할 수 없습니다,하지만 난 암시 퍼팅 한 폭 넓은 질문이었다. 내가 찌른 사람 한테 불공평하다는 걸 알아, 미안해!

+1

t2의 열 a, b 및 c의 정의에 따라 이것은 틀릴 수 있습니다! 그들이 NULL 값을 허용하면 NOT IN에 대한 결과는 그러한 값에 대해 항상 알려지지 않습니다. NOT EXISTS *는 이것을 표현하는 올바른 방법입니다. 존재하지 않는 것은 이것을 위해서 만들어졌습니다. – wich

+0

굉장! 감사. – user151841

3

제공되는 답변을 사용해도이 쿼리를 실행할 수있는 올바른 방법을 찾지 못했습니다. 나는 내가 필요한 MySQL의 문서 참조를 발견

SELECT DISTINCT store_type FROM stores WHERE NOT EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type);

나는 주위에 하위 쿼리 내부의 첫 번째 쿼리에서 '저장'테이블에 대한 참조를 사용하던 내 머리를 포장했다 트릭. 희망이 도움이 (이 오래된 스레드이기 때문에, 또는 다른 사람을 도움이됩니다.)