Xóa các hàng sql nơi ID không khớp với bảng khác


160

Tôi đang cố gắng xóa các mục mồ côi trong bảng mysql.

Tôi có 2 bảng như thế này:

Bảng files:

| id | ....
------------
| 1  | ....
| 2  | ....
| 7  | ....
| 9  | ....

bảng blob:

| fileid | ....
------------
| 1  | ....
| 2  | ....
| 3  | ....
| 4  | ....
| 4  | ....
| 4  | ....
| 9  | ....

Các cột fileididcó thể được sử dụng để nối các bảng lại với nhau.

Tôi muốn xóa tất cả các hàng trong bảng blobnơi fileidkhông thể tìm thấy trong bảng files.id.

Vì vậy, sử dụng ví dụ trên sẽ xóa các hàng: 3 & 4 (s) trong blobbảng.


1
Bỏ qua câu trả lời thứ hai nếu bạn đang sử dụng nulls.
Pacerier

Câu trả lời:


326

Sử dụng TRÁI PHIẾU / LÀ NULL:

DELETE b FROM BLOB b 
  LEFT JOIN FILES f ON f.id = b.fileid 
      WHERE f.id IS NULL

Sử dụng KHÔNG EXISTS:

DELETE FROM BLOB 
 WHERE NOT EXISTS(SELECT NULL
                    FROM FILES f
                   WHERE f.id = fileid)

Sử dụng KHÔNG VÀO:

DELETE FROM BLOB
 WHERE fileid NOT IN (SELECT f.id 
                        FROM FILES f)

Cảnh báo

Bất cứ khi nào có thể, hãy thực hiện XÓA trong một giao dịch (giả sử được hỗ trợ - IE: Không phải trên MyISAM) để bạn có thể sử dụng rollback để hoàn nguyên các thay đổi trong trường hợp có vấn đề.


12
đó là, nói chung, nhanh nhất trong số trên?
Hampus Brynolf

2
Vì một số lý do, việc xóa bằng cách sử dụng LEFT THAM GIA không hoạt động trên MS SQL Server Mgmt Studio (không rõ tại sao; nó chỉ phàn nàn về LEFT THAM GIA). Có ai biết tại sao lại như vậy không? Nó hoạt động bằng cách sử dụng KHÔNG EXISTS :)
Anna

5
FYI, đây là một cuộc thảo luận hữu ích của hiệu quả tương đối của ba phương pháp: explainextended.com/2009/09/18/...
moustachio

2
@Pacerier - "sai" là một chút mạnh mẽ. Để đảm bảo mọi người đều hiểu, câu trả lời làm việc nếu fileidkhông nullable . Ngoài ra, giải pháp thứ ba ( NOT IN) chỉ yêu cầu điều đó f.idbởi không thể rỗng. Có lẽ đó là một khóa chính, vì vậy nó sẽ được.
ToolmakerSteve

2
Đối với những người đang thử w / SQLite này: hãy xem câu trả lời này
bunkerdive

26
DELETE FROM blob 
WHERE fileid NOT IN 
       (SELECT id 
        FROM files 
        WHERE id is NOT NULL/*This line is unlikely to be needed 
                               but using NOT IN...*/
      )

Là gì "/ * Dòng này là khó có thể cần thiết nhưng sử dụng NOT IN ... * /" có nghĩa là gì?
Pacerier

1
@Pacerier - NOT IN (NULL)trả về một tập kết quả trống để NULL cần được loại trừ. Nhưng iddù sao thì một cột có thể sẽ không thể bị vô hiệu hóa do đó "không cần thiết"
Martin Smith

Wow bắt tốt. Vì vậy, câu trả lời của omgponies là sai! not in(null)là khá logic, tại sao nó không hoạt động? Lý do đằng sau đó là gì?
Pacerier


1
@bunkerdive Sau đó sử dụng ba tên đối tượng bao gồm tên cơ sở dữ liệu.
Martin Smith

17
DELETE FROM blob
WHERE NOT EXISTS (
    SELECT *
    FROM files
    WHERE id=blob.id
)

1
Tôi nghĩ rằng có một files.idblob.fileid. Tôi đoán truy vấn của bạn sẽ dẫn đến một lỗi.
giờ 45 phút

-8
delete from table1 t1 
    WHERE not exists (select id from table2 where related_field_in_t2=t1.id) 
    AND not exists (select id from table3 where related_field_in_t3=t1.id) 
    AND not exists (select id from table4 where related_field_t4=t1.id) 
    AND not exists (select id from table5 where related_field_t5=t1.id);

3
Tôi đã hạ cấp vì: 1. Điều này không cố gắng trả lời câu hỏi trong ngữ cảnh được đăng. 2. Không có lời giải thích (và câu trả lời chỉ có mã là giá trị thấp trên Stackoverflow). 3. NOT EXISTSđã được đăng 9 năm trước. 4. Bạn chưa thúc đẩy cách thực hành tốt nhất là sử dụng tất cả các từ khóa cho các từ khóa MySQL. Nói cách khác, không có gì ở đây đáng để giữ - đây là lý do tại sao tôi cũng đã bỏ phiếu để xóa bài đăng này.
mickmackusa
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.