Table1
다른 테이블 ( Table2
) 의 열에 주요 열 값이없는 곳의 모든 행을 던지기 위해 간단한 쿼리를 실행하고 싶었습니다 .
나는 다음을 사용하려고 시도했다.
SELECT * FROM Table1 WHERE Table1.principal NOT IN Table2.principal
대신 구문 오류가 발생합니다. 구글 검색을 통해 사람들이 MySQL을 지원하지 않으며 NOT IN
매우 복잡한 것을 사용해야하는 포럼으로 이끌었습니다 . 이것이 사실입니까? 아니면 끔찍한 실수를 저지르고 있습니까?
답변
IN을 사용하려면 세트가 있어야합니다. 대신이 구문을 사용하십시오.
SELECT * FROM Table1 WHERE Table1.principal NOT IN (SELECT principal FROM table2)
답변
하위 쿼리 옵션은 이미 답변되었지만 대부분의 LEFT JOIN
경우이 작업을 수행하는 더 빠른 방법 일 수 있습니다.
SELECT table1.*
FROM table1 LEFT JOIN table2 ON table2.principal=table1.principal
WHERE table2.principal IS NULL
SRKR의 의견과 같이 여러 테이블을 확인하여 테이블에 없는지 확인하려면 다음을 사용할 수 있습니다.
SELECT table1.*
FROM table1
LEFT JOIN table2 ON table2.name=table1.name
LEFT JOIN table3 ON table3.name=table1.name
WHERE table2.name IS NULL AND table3.name IS NULL
답변
NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL in MySQL
MySQL과 SQL Server를 제외한 다른 모든 시스템 은 일치하는 값을 찾 자마자 최적화
LEFT JOIN
/IS NULL
반환 할 수FALSE
있으며이 동작을 문서화 한 유일한 시스템입니다. […] MySQL은 알고리즘 을 사용HASH
하고MERGE
결합 할 수 없기 때문에 유일ANTI JOIN
하게 가능한 것은NESTED LOOPS ANTI JOIN
[…]
본질적으로, [
NOT IN
] 는 이 계획들이 서로 다른 코드의 분기에 의해 실행되고 결과에서 다르게 보인다는 사실에도 불구하고LEFT JOIN
/IS NULL
사용 과 정확히 같은 계획 입니다EXPLAIN
. 알고리즘은 실제로 동일하며 쿼리는 동시에 완료됩니다.
[…]
이 하락은 선형이며 두 필드가 모두 색인화되어있는 한 데이터 분산, 두 테이블의 값 수 등에 의존하지 않는 것이므로 [사용시 성능 저하
NOT EXISTS
]의 정확한 이유를 말하기는 어렵습니다 . MySQL에는 본질적으로 하나의 작업을 수행하는 세 가지 코드가 있기 때문에 책임이있는 코드EXISTS
는 추가 시간이 걸리는 추가 검사를 수행 할 수 있습니다.
[…]
MySQL은 세 가지 방법을 모두 최적화하여 일종의 작업을 수행 할 수 있습니다
NESTED LOOPS ANTI JOIN
. […] 그러나이 세 가지 방법은 세 가지 다른 코드 조각으로 실행되는 세 가지 다른 계획을 생성합니다.EXISTS
술어 를 실행하는 코드 는 약 30 % 덜 효율적입니다 […]그렇기 때문에 MySQL에서 결 측값을 검색 하는 가장 좋은 방법은
LEFT JOIN
/IS NULL
또는NOT IN
대신을 사용하는 것NOT EXISTS
입니다.
(단계 추가)
답변
불행히도 “NOT IN”절의 MySql 사용에 문제가있는 것 같습니다. 아래의 스크린 샷은 잘못된 결과를 반환하는 하위 쿼리 옵션을 보여줍니다.
mysql> show variables like '%version%';
+-------------------------+------------------------------+
| Variable_name | Value |
+-------------------------+------------------------------+
| innodb_version | 1.1.8 |
| protocol_version | 10 |
| slave_type_conversions | |
| version | 5.5.21 |
| version_comment | MySQL Community Server (GPL) |
| version_compile_machine | x86_64 |
| version_compile_os | Linux |
+-------------------------+------------------------------+
7 rows in set (0.07 sec)
mysql> select count(*) from TABLE_A where TABLE_A.Pkey not in (select distinct TABLE_B.Fkey from TABLE_B );
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.07 sec)
mysql> select count(*) from TABLE_A left join TABLE_B on TABLE_A.Pkey = TABLE_B.Fkey where TABLE_B.Pkey is null;
+----------+
| count(*) |
+----------+
| 139 |
+----------+
1 row in set (0.06 sec)
mysql> select count(*) from TABLE_A where NOT EXISTS (select * FROM TABLE_B WHERE TABLE_B.Fkey = TABLE_A.Pkey );
+----------+
| count(*) |
+----------+
| 139 |
+----------+
1 row in set (0.06 sec)
mysql>
답변
주의 NOT IN
는의 별칭이 <> ANY
아니라 <> ALL
!
http://dev.mysql.com/doc/refman/5.0/en/any-in-some-subqueries.html
SELECT c FROM t1 LEFT JOIN t2 USING (c) WHERE t2.c IS NULL
로 대체 될 수 없다
SELECT c FROM t1 WHERE c NOT IN (SELECT c FROM t2)
당신은 사용해야합니다
SELECT c FROM t1 WHERE c <> ANY (SELECT c FROM t2)