J'ai deux tables dans une base de données PostgreSQL 9.3: Table link_reply
possède une clé étrangère nommée which_group
pointant vers le tableau link_group
.
Je souhaite supprimer toutes les lignes de link_group
où aucune ligne associée dans link_reply
existe. Cela semble assez basique mais j'ai eu du mal avec.
Sera-ce quelque chose de simple comme ça (ne fonctionne pas)?
DELETE FROM link_group WHERE link_reply = NULL;
Il existe deux façons de supprimer des lignes dans une table en utilisant les informations contenues dans d'autres tables de la base de données: en utilisant des sous-sélections ou en spécifiant des tables supplémentaires dans la clause
USING
. La technique la plus appropriée dépend des circonstances spécifiques.
Accentuation sur moi. L'utilisation d'informations pas contenues dans un autre tableau est un peu délicate, mais il existe des solutions faciles. De l'arsenal des techniques standards au ...
... une NOT EXISTS
l'anti-semi-jointure est probablement la plus simple et la plus efficace pour DELETE
:
DELETE FROM link_group lg
WHERE NOT EXISTS (
SELECT FROM link_reply lr
WHERE lr.which_group = lg.link_group_id
);
En supposant (puisque les définitions de table ne sont pas fournies) link_group_id
comme nom de colonne pour la clé primaire de link_group
.
La technique @ Mihai a commenté fonctionne aussi (appliquée correctement):
DELETE FROM link_group lg
USING link_group lg1
LEFT JOIN link_reply lr ON lr.which_group = lg1.link_group_id
WHERE lg1.link_group_id = lg.link_group_id
AND lr.which_group IS NULL;
Mais puisque l'expression de table dans la clause USING
est jointe à la table cible (lg
dans l'exemple) avec un CROSS JOIN
, vous avez besoin d'une autre instance de la même table que le tremplin (lg1
dans l'exemple) pour le LEFT JOIN
, qui est moins élégant et généralement plus lent.