2013-04-16 20 views
10

Mam problem z usuwaniem rekordów z tabeli PostgreSQL przy użyciu LEFT JOIN.Jak usunąć wiersze za pomocą zewnętrznego łączenia

Chciałbym usunąć wiersze dostaję z następującym zapytaniem:

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

Aby to zrobić, tutaj jest to, co robiłam:

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

prace Query ale niczego nie usuwać , chociaż dokładnie to wyjaśniono w dokumencie: http://www.postgresql.org/docs/current/static/sql-delete.html.

Czy mój problem wynika z pytania IS NULL w zapytaniu lub czy czegoś mi brakuje?

+4

Nie usuwa niczego, ponieważ gdy 'link_type.id' ma wartość null,' url.link_type = link_type.id' nie jest prawdziwe, więc te dwa warunki nigdy nie są spełnione łącznie. –

Odpowiedz

6

Nadal nie rozumiem, dlaczego mój poprzedni kwerenda nie działa (jeśli ktoś może wyjaśnić, byłoby miło), ale tutaj jest jak zrobiłem trick:

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

Bo jeśli "url.link_type = link_type.id" jest "TRUE", to "link_type.id" _ nie jest "NULL" _, jeśli "link_type.id" jest "NULL" pierwszy warunek "url.link_type = link_type.id "zwróci" NULL "również wtedy otrzymasz" NULL AND TRUE ", który jest po prostu" NULL ". Ponieważ wartość NULL jest nieznaną wartością, nie można powiedzieć, że ma wartość PRAWDA lub FAŁSZ, więc nie są wyświetlane żadne wiersze. NOT EXISTS wykonają dla ciebie pracę. – Guedes

10

Dobra robota, słoneczny. Drobne sugestie: gdy korzystasz z EXISTS/NOT EXISTS, nie potrzebujesz SELECT *. Wspólna konwencja (docs) jest po prostu napisać SELECT 1 jak tak:

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

Funkcjonalnie oba sposoby pracy.