2017-05-18 3 views
0

Je cherche à faire quelque chose le long des lignes de:SQL: Pour chaque ligne, vérifier une condition comportant un élément de cette ligne

Pour chaque ligne dans une table, vérifier s'il y a des enfants (ce qui est fait par sélectionner tous les éléments avec un parentid égal à l'identifiant de l'élément courant). Si rien n'apparaît, alors il n'y a pas d'enfants et le parent doit être supprimé. Ce parentid doit provenir de l'identifiant de l'élément courant.

Je pensais quelque chose le long des lignes de (en pseudo-code-ish):

DELETE FROM table WHERE ((SELECT * FROM table WHERE parentid = id) IS NULL) 

Idéalement, je ferais un pour chaque boucle, et créer une variable (notez que j'écris ceci dans C#) pour l'identifiant courant à utiliser pour la recherche de parentid.

Je pense que je peux négliger une approche plus facile ... Existe-t-il un moyen plus facile de mettre en œuvre cela? Si non, l'approche est-elle correcte et comment pourrais-je traduire cela en SQL?

De toute façon, toute aide est appréciée.

+2

"Idéalement, je ferais un pour chaque boucle" - non, idéalement, vous y penseriez en termes de [set operations] (http://www.cs.odu.edu/~toida/nerzic/level-a/ set/set_operations.html), qui est ce à quoi les bases de données relationnelles excellent, au lieu des boucles impératives. – DigiFriend

Répondre

0

ce serait pas sûr de la syntaxe droite, mais ce que vous recherchez est une liste de tous les parentid s - ce qui peut être interrogé à partir table en allant chercher toutes les valeurs parentid de lui. Une fois que vous avez cette liste, vous voulez supprimer tous les éléments qui sont pas en elle et n'ont pas parentid de leur propre:

DELETE FROM table 
WHERE id NOT IN 
(
    SELECT parentid FROM table 
) 
AND parentid IS NULL -- assumption: parents do not have a parent id 
+0

Par sécurité, et pour tester avant de faire quelque chose d'irrévocable, remplacez le 'DELETE' par un' SELECT' pour voir que la requête retourne les lignes attendues et rien d'autre. – DigiFriend

0

Sélection de lignes qui ont pas d'enfants avec not exists():

--delete t 
select * 
from tbl t 
where not exists (
    select 1 
    from tbl i 
    where t.id = i.parentid 
)