2013-04-16 4 views
10

У меня проблема с удалением записей из таблицы PostgreSQL с использованием LEFT JOIN.Как удалить строки с помощью внешнего соединения

Я хотел бы, чтобы удалить строки, которые я получаю с помощью следующего запроса:

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

Чтобы сделать это, вот что я сделал:

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

запрос работает, но ничего не удалять , хотя это именно то, что объясняется в документе: http://www.postgresql.org/docs/current/static/sql-delete.html.

Является ли моя проблема из-за IS NULL в запросе или я чего-то не хватает?

+4

Это не удаляет ничего, потому что, когда 'link_type.id' равно null,' url.link_type = link_type.id' неверно, поэтому эти два условия никогда не выполняются вместе. –

ответ

6

До сих пор не понимаю, почему мой предыдущий запрос не работает (если кто-то может объяснить, было бы неплохо), но вот как я сделал трюк:

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

Потому что, если «url.link_type = link_type.id» «TRUE», то «link_type.id» _is не «NULL» _, если «link_type.id» является «NULL», первое условие «url.link_type = link_type.id "также вернет" NULL ", после чего вы получите" NULL AND TRUE ", который будет просто" NULL ". Поскольку значение NULL является неизвестным, вы не можете сказать, что оно TRUE или FALSE, поэтому строки не отображаются. НЕ СУЩЕСТВУЮТ для вашей работы. – Guedes

10

Хорошая работа, солнце. Незначительное предложение: при использовании EXISTS/NOT EXISTS вам не нужно SELECT *. Общая конвенция (docs) является просто написать SELECT 1, как например:

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

Функционально оба способа работает.

Смежные вопросы