programing

한 테이블에서 다른 테이블에 존재하지 않는 레코드 찾기

procenter 2022. 9. 28. 22:58
반응형

한 테이블에서 다른 테이블에 존재하지 않는 레코드 찾기

MySQL에는 다음 두 개의 테이블이 있습니다.

Phone_book
+----+------+--------------+
| id | name | phone_number |
+----+------+--------------+
| 1  | John | 111111111111 |
+----+------+--------------+
| 2  | Jane | 222222222222 |
+----+------+--------------+

Call
+----+------+--------------+
| id | date | phone_number |
+----+------+--------------+
| 1  | 0945 | 111111111111 |
+----+------+--------------+
| 2  | 0950 | 222222222222 |
+----+------+--------------+
| 3  | 1045 | 333333333333 |
+----+------+--------------+

어떤 전화가 걸려왔는지 어떻게 알 수 있나요?phone_number에 없습니다.Phone_book원하는 출력은 다음과 같습니다.

Call
+----+------+--------------+
| id | date | phone_number |
+----+------+--------------+
| 3  | 1045 | 333333333333 |
+----+------+--------------+

쿼리 옵티마이저가 얼마나 우수한지, 두 테이블의 상대적 크기에 따라 효율성이 달라지는 여러 가지 방법이 있습니다.

이것은 가장 짧은 문장으로 전화번호부가 매우 짧은 경우 가장 빠른 문장이 될 수 있습니다.

SELECT  *
FROM    Call
WHERE   phone_number NOT IN (SELECT phone_number FROM Phone_book)

또는 (Alterlife 덕분에)

SELECT *
FROM   Call
WHERE  NOT EXISTS
  (SELECT *
   FROM   Phone_book
   WHERE  Phone_book.phone_number = Call.phone_number)

또는 (WOPR 덕분에)

SELECT * 
FROM   Call
LEFT OUTER JOIN Phone_Book
  ON (Call.phone_number = Phone_book.phone_number)
  WHERE Phone_book.phone_number IS NULL

(다른 사람이 말한 것처럼 보통 원하는 열만 선택하는 것이 가장 좋습니다.)*')

SELECT Call.ID, Call.date, Call.phone_number 
FROM Call 
LEFT OUTER JOIN Phone_Book 
  ON (Call.phone_number=Phone_book.phone_number) 
  WHERE Phone_book.phone_number IS NULL

쿼리 옵티마이저가 마법을 사용할 수 있도록 하위 쿼리를 제거해야 합니다.

또한 "SELECT *"는 다른 사용자가 기본 테이블 또는 보기를 변경할 경우(그리고 비효율적) 코드가 끊어질 수 있으므로 피하십시오.

다음 코드는 대규모 데이터셋을 처리할 때 위에 제시된 답변보다 조금 더 효율적입니다.

SELECT *
FROM Call
WHERE NOT EXISTS (
    SELECT 'x'
    FROM Phone_book
    WHERE Phone_book.phone_number = Call.phone_number
);
SELECT DISTINCT Call.id 
FROM Call 
LEFT OUTER JOIN Phone_book USING (id) 
WHERE Phone_book.id IS NULL

그러면 Phone_book 테이블에 누락된 추가 ID가 반환됩니다.

생각합니다

SELECT CALL.* FROM CALL LEFT JOIN Phone_book ON 
CALL.id = Phone_book.id WHERE Phone_book.name IS NULL
SELECT t1.ColumnID,
CASE 
    WHEN NOT EXISTS( SELECT t2.FieldText  
                     FROM Table t2 
                     WHERE t2.ColumnID = t1.ColumnID) 
    THEN t1.FieldText
    ELSE t2.FieldText
END FieldText       
FROM Table1 t1, Table2 t2
SELECT name, phone_number FROM Call a
WHERE a.phone_number NOT IN (SELECT b.phone_number FROM Phone_book b)

또,

select id from call
minus
select id from phone_number

인덱스를 확인하는 것을 잊지 마세요!

테이블이 꽤 큰 경우 전화번호부에 인덱스가 있는지 확인해야 합니다.phone_number테이블이 클 경우 데이터베이스는 두 테이블을 모두 검색하도록 선택할 수 있습니다.

SELECT *
FROM   Call
WHERE  NOT EXISTS
  (SELECT *
   FROM   Phone_book
   WHERE  Phone_book.phone_number = Call.phone_number)

인덱스를 둘 다 생성해야 합니다.Phone_Book그리고.Call포함phone_number성능이 문제가 될 경우 전화번호만 사용하여 다음과 같은 린 인덱스를 사용해 보십시오.

필드를 모두 로드해야 하므로 필드가 적을수록 좋습니다.두 테이블 모두에 색인이 필요합니다.

ALTER TABLE [dbo].Phone_Book ADD CONSTRAINT [IX_Unique_PhoneNumber] UNIQUE NONCLUSTERED 
(
    Phone_Number
)
WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ONLINE = ON) ON [PRIMARY]
GO

쿼리 플랜을 보면 다음과 같이 표시되며 새 인덱스가 실제로 사용되고 있는지 확인할 수 있습니다.이는 SQL Server용이지만 MySQL용과 비슷해야 합니다.

제가 보여드린 쿼리에서 데이터베이스를 통해 결과를 얻을 수 있는 방법은 두 테이블의 모든 레코드를 스캔하는 것 외에 없습니다.

여기에 이미지 설명 입력

언급URL : https://stackoverflow.com/questions/367863/find-records-from-one-table-which-dont-exist-in-another

반응형