세 테이블에 걸친 MySQL "NOT IN" 쿼리: 함정 및 해결 방법
MySQL에서는 "NOT IN" 연산자가 일반적으로 사용됩니다. 지정된 테이블에 존재하지 않는 레코드를 검색합니다. 그러나 여러 테이블로 작업할 때는 잠재적인 함정을 인식하는 것이 중요합니다.
"NOT IN"으로 인해 예상치 못한 결과가 발생할 수 있는 시나리오 중 하나는 검색 중인 테이블에 NULL 값이 포함될 수 있는 경우입니다. 이 문제는 "등급" 및 "평가" 테이블의 데이터를 비교하는 쿼리에서 발생했습니다. 쿼리는 "evaluation"의 항목과 일치하지 않는 "grade"의 레코드를 식별하는 것을 목표로 했지만 "JOHN"이라는 이름이 두 테이블 모두에 없으면 결과를 반환하지 못했습니다.
이를 방지하려면 문제가 있는 경우 "NOT IN" 대신 NOT EXISTS 또는 왼쪽 조인과 같은 대체 방법을 사용하는 것이 좋습니다. 이러한 접근 방식은 NULL 값으로 인해 쿼리가 중단될 가능성이 없습니다.
또한 WHERE 절을 사용하여 테이블을 조인하는 레거시 구문보다는 명시적 조인을 사용하는 것이 좋습니다. 명시적 조인은 더 큰 명확성을 제공하고 잠재적인 성능 문제를 방지합니다.
NULL 값을 처리할 때 "NOT IN"의 단점을 더 자세히 설명하려면 다음 예를 고려하십시오.
테이블 구조:
CREATE TABLE mStatus ( id INT AUTO_INCREMENT PRIMARY KEY, status VARCHAR(10) NOT NULL ); INSERT INTO mStatus (status) VALUES ('single'),('married'),('divorced'),('widow'); CREATE TABLE people ( id INT AUTO_INCREMENT PRIMARY KEY, fullName VARCHAR(100) NOT NULL, status VARCHAR(10) NULL );
청크 1:
TRUNCATE TABLE people; INSERT INTO people (fullName, status) VALUES ('John Henry','single'); SELECT * FROM mStatus WHERE status NOT IN (SELECT status FROM people);
예상 결과: 3행(예상대로)
청크 2:
TRUNCATE TABLE people; INSERT INTO people (fullName, status) VALUES ('John Henry','single'),('Kim Billings',NULL); SELECT * FROM mStatus WHERE status NOT IN (SELECT status FROM people);
예상치 못한 일 결과: 반환된 행이 없습니다
이 예상치 못한 동작은 MySQL에서 사용하는 세 값 논리로 인해 발생합니다. NULL 값이 포함된 경우 쿼리는 다음과 같이 변환됩니다.
status NOT IN ('single', 'married', 'widowed', NULL)
이것은 다음과 같습니다.
NOT(status='single' OR status='married' OR status='widowed' OR status=NULL)
"status=NULL" 표현식이 UNKNOWN으로 평가되므로 전체 표현식은 다음과 같습니다. UNKNOWN, 모든 행이 필터링됨 out.
해결책:
이 문제를 방지하려면 Left 조인 또는 NOT EXISTS와 같은 대체 접근 방식을 사용하세요.
SELECT s.status FROM mStatus s LEFT JOIN people p ON p.status=s.status WHERE p.status IS NULL
또는
SELECT s.status FROM mStatus s WHERE NOT EXISTS (SELECT 1 FROM people p WHERE p.status=s.status)
위 내용은 MySQL의 'NOT IN'이 여러 테이블에서 NULL로 인해 실패하는 이유는 무엇이며 어떻게 해결할 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!