J'ai le DAG suivant
DELETE FROM `Closure` WHERE `Descendant` IN (SELECT `Descendant` FROM `Closure` WHERE `Ancestor`=@Node) AND `Ancestor` NOT IN (SELECT `Descendant` FROM `Closure` WHERE `Ancestor`=@Node);
4 Réponses :
En langage naturel, ce serait: "Supprimer les relicotions descendantes de l'ancêtre à D, s'il n'y a pas de parent de D en plus de B qui est également un descendant d'un". Est-ce correct?
( éditer: em> non, ce n'est pas correct; non seulement des relicotions à D doivent être supprimées, mais aussi des relicotions à chaque descendant de D forte>. Ainsi, que les critères ne sont pas valides ...) p> mon SQL provisoire serait alors: p> (désolé si j'ai eu la mauvaise requête - ou utilisé non - Caractéristiques standard - Je ne suis pas réellement expérimenté avec ça. Mais ma description de la langue naturelle devrait donner une idée de ce qui doit réellement aller sur la requête) p> Mise à jour: forte > À la deuxième pensée, je ne crois pas que ma requête fonctionnera pour tous les cas. Considérez ceci: p>
A --> B --> D --> E --> F
Tout d'abord, je crois qu'il y a une entrée en double dans votre table. Ainsi, pour retirer le bord (a, d) code> apparaît deux fois. Deuxièmement, après avoir retiré le bord
(b, d) code>, les chemins suivants doivent rester:
(a, a) code>,
(B, B) code>,
(c, c) code>,
(D, D) CODE> LI>
(a, b) code> li>
(a, c) code> li>
(a, d) code> (via c) li>
ol>
(b, d) code> Dans cet exemple, tout ce qui est nécessaire est de supprimer celui-ci: P>
Delete MyTable
Where Ancestor = 'B'
And Descendant = 'D'
Le duplicata (A, D) est en réalité la racine de cette question - il existe pour montrer que dans une table de fermeture, vous en auriez un (A, D) causé par ABD et un de l'ACD. Comment détecter-je quand un autre chemin coupe-ps dans ce diamant et non supprimé (A, D)? De préférence uniquement en utilisant SQL et uniquement le bord (B, D).
@NTSCCOBALT - Il n'a aucun sens d'avoir (a, d) code> là-bas deux fois. Une table de fermeture ne décrit pas comment i> un nœud se connecte avec un autre; seulement que i> un nœud se connecte avec un autre. Ainsi, si
(a, d) code> est dans la table, il n'a pas d'importance si le chemin d'accès à partir de
a code> à
d code> était < Code> A> B> C> E> .....> x> y> d code> ou
a> d code>. C'est le but. Le tableau de fermeture vous évite de devoir calculer ce chemin à chaque fois. Si vous essayez de capturer les chemins utilisés pour obtenir un nœud à un autre, une table de fermeture n'est pas la solution. Planifiez plutôt le graphique dans une table des bords et calculez le chemin.
Ah, oui, j'ai du mal à me souvenir pourquoi j'ai demandé à cette question d'être honnête. Je ne me souviens pas vraiment de ce que nous avons décidé de faire en solution. Je pense que l'intention initiale était de comprendre un moyen de supprimer le bord de (B, D) et de supprimer toutes les entrées dans la table de fermeture causée par elle sans retirer accidentellement les bords qui existent toujours. La seule solution que je puisse penser immédiatement à reconstruire la totalité de la table de fermeture des nœuds que vous savez ne sont que 1 à pas.
Compte tenu de votre modèle actuel, je ne suis pas sûr que ce soit possible. Je proposerais que vous ajoutez une colonne pour compter le nombre de chemins suivis du nombre de manières différentes à partir de tout nœud Plutôt que votre table, vous vous retrouvez avec p> supprimer un nœud impliquerait alors une instruction de mise à jour suivie d'une instruction DELETE.
La mise à jour aurait, au lieu de supprimer les entrées qu'il trouve, décrémentez le nombre de références pour cette entrée. Ensuite, vous pouvez supprimer les entrées avec 0 ou moins de références par la suite. P> À venir avec une requête SQL qui me fait échapper à la mise à jour pour le moment, mais en théorie, cela devrait fonctionner sans avoir à reconstruire complètement la table de fermeture ... p> p> x code> au noeud
y code>.
Approche intéressante. Je me demande si plusieurs références d'ancêtre à descendre pourraient avoir des profondeurs différentes, comment mettrez-vous à jour la profondeur si l'un des REF est supprimé?
Tout en suivant la profondeur et permettant à plusieurs parents en même temps est probablement possible, je reçois une odeur de code de celui-ci, surtout lorsque la solution implique d'avoir des deux couples. Thomas 'Réponse des contours qui émettent .
Je vais simplifier la question un peu pour vous concentrer sur Vous devez prendre en compte les enfants de D, ce qui est compliqué rapidement. Disons que nous avons: p> Nous voulons dissimuler d de b, ce qui signifie que nous devons également supprimer les liens entre E et B. mais si elles sont connectées comme ceci: p> Dans ce cas si nous déconnectons b> d, nous ne voulons plus non plus, car e est toujours lié à B à C. mais nous faisons Voulez-vous déconnecter F de b. P> Je vais passer par ma solution ci-dessous en utilisant ce deuxième exemple. Je sais que D n'a qu'un parent dans cet exemple, mais cela fonctionne toujours parfaitement si D a plusieurs parents; Je peux plus facilement démontrer certains des cas de bord de cette façon, c'est pourquoi je le fais comme ça. P> Voici ce que la table ressemblerait à: p> Query 1: Obtenez tous les descendants de D, y compris d strud> p> Ceci retournera: Query 2: Obtenez tous les ancêtres de B, y compris B STRY> P> d, e, f Code> p>
A --> B --> C
|
v
D --> E < -- G
|
V
H --> F