2013-04-16 20 views
10

Tôi gặp sự cố khi xóa bản ghi khỏi bảng PostgreSQL, sử dụng LEFT JOIN.Cách xóa các hàng bằng cách sử dụng phép nối ngoài

Tôi muốn xóa hàng tôi nhận được với các truy vấn sau đây:

SELECT * FROM url 
LEFT JOIN link_type ON url.link_type = link_type.id 
WHERE link_type.id IS NULL 

Để làm như vậy, đây là những gì tôi đã làm:

DELETE FROM url 
USING link_type 
WHERE url.link_type = link_type.id AND link_type.id IS NULL 

công trình Query nhưng không xóa bất cứ điều gì , mặc dù đó là chính xác những gì được giải thích trong tài liệu: http://www.postgresql.org/docs/current/static/sql-delete.html.

Vấn đề của tôi là do IS NULL trong truy vấn hoặc Tôi thiếu gì đó?

+4

Nó không xóa bất cứ điều gì vì khi 'link_type.id' là null,' url.link_type = link_type.id' không đúng nên hai điều kiện này không bao giờ được thỏa mãn với nhau. –

Trả lời

6

Vẫn không hiểu tại sao truy vấn trước đây của tôi không hoạt động (nếu ai đó có thể giải thích, sẽ được tốt đẹp), nhưng đây là cách tôi đã làm các trick:

DELETE FROM url WHERE NOT EXISTS (SELECT * FROM link_type WHERE url.link_type = link_type.id); 
+2

Bởi vì nếu "url.link_type = link_type.id" là "TRUE" thì "link_type.id" _is not "NULL" _, nếu "link_type.id" là "NULL" thì điều kiện đầu tiên "url.link_type = link_type.id "sẽ trả về" NULL "quá sau đó bạn nhận được" NULL VÀ TRUE "đó chỉ là" NULL ". Vì NULL là một giá trị unknow bạn không thể nói rằng nó là TRUE hoặc FALSE, do đó không có hàng nào được hiển thị. Không tồn tại sẽ cho công việc cho bạn. – Guedes

10

Làm tốt lắm, mặt trời. Đề xuất nhỏ: khi sử dụng EXISTS/NOT EXISTS bạn không cần phải SELECT *. Một quy ước chung (docs) là chỉ cần viết SELECT 1 như như thế này:

DELETE FROM url WHERE NOT EXISTS (
    SELECT 1 FROM link_type WHERE url.link_type = link_type.id 
); 

Về mặt chức năng, cả hai cách làm việc.

Các vấn đề liên quan