두 테이블을 조인하는 MySQL 쿼리가 있습니다.
- 유권자
- 가구
그들은에 가입 voters.household_id
하고 household.id
.
이제 내가 뭘해야 유권자 테이블이 함께 제거라는 세 번째 테이블에 조인되는 경우를 수정하는 것입니다 voter.id
및 elimination.voter_id
. 그러나 문제는 제거 테이블에 해당 레코드가있는 유권자 테이블의 모든 레코드를 제외하고 싶다는 것입니다.
이 작업을 수행하는 쿼리를 어떻게 작성합니까?
이것은 내 현재 쿼리입니다.
SELECT `voter`.`ID`, `voter`.`Last_Name`, `voter`.`First_Name`,
`voter`.`Middle_Name`, `voter`.`Age`, `voter`.`Sex`,
`voter`.`Party`, `voter`.`Demo`, `voter`.`PV`,
`household`.`Address`, `household`.`City`, `household`.`Zip`
FROM (`voter`)
JOIN `household` ON `voter`.`House_ID`=`household`.`id`
WHERE `CT` = '5'
AND `Precnum` = 'CTY3'
AND `Last_Name` LIKE '%Cumbee%'
AND `First_Name` LIKE '%John%'
ORDER BY `Last_Name` ASC
LIMIT 30
답변
LEFT JOIN
일치하는 항목이 없어도 행을 반환하는을 사용하고 NULL
s 를 확인하여 일치하지 않는 행만 선택할 수 있습니다 .
따라서 다음과 같습니다.
SELECT V.*
FROM voter V LEFT JOIN elimination E ON V.id = E.voter_id
WHERE E.voter_id IS NULL
하위 쿼리를 사용하는 것보다 효율성이 떨어지는 지 여부는 최적화, 인덱스, 투표자 당 둘 이상의 제거가 가능한지 여부 등에 따라 다릅니다.
답변
제목에서 제안한대로 정확히 ‘존재하지 않는 곳’을 사용합니다.
SELECT `voter`.`ID`, `voter`.`Last_Name`, `voter`.`First_Name`,
`voter`.`Middle_Name`, `voter`.`Age`, `voter`.`Sex`,
`voter`.`Party`, `voter`.`Demo`, `voter`.`PV`,
`household`.`Address`, `household`.`City`, `household`.`Zip`
FROM (`voter`)
JOIN `household` ON `voter`.`House_ID`=`household`.`id`
WHERE `CT` = '5'
AND `Precnum` = 'CTY3'
AND `Last_Name` LIKE '%Cumbee%'
AND `First_Name` LIKE '%John%'
AND NOT EXISTS (
SELECT * FROM `elimination`
WHERE `elimination`.`voter_id` = `voter`.`ID`
)
ORDER BY `Last_Name` ASC
LIMIT 30
왼쪽 조인을 수행하는 것보다 약간 더 빠를 수 있으며 (물론 인덱스, 테이블의 카디널리티 등에 따라 다름) IN을 사용하는 것보다 훨씬 빠릅니다.
답변
이를 수행하는 세 가지 가능한 방법이 있습니다.
-
선택권
SELECT lt.* FROM table_left lt LEFT JOIN table_right rt ON rt.value = lt.value WHERE rt.value IS NULL
-
선택권
SELECT lt.* FROM table_left lt WHERE lt.value NOT IN ( SELECT value FROM table_right rt )
-
선택권
SELECT lt.* FROM table_left lt WHERE NOT EXISTS ( SELECT NULL FROM table_right rt WHERE rt.value = lt.value )