SQL-Entwickler, ich habe eine schlecht geplante Datenbank als Aufgabe, um viel über SQL Server 2012 zu lernen.
SO gibt es die Tabelle Elem
:
+-----------+----+---+----------+------------+
|VERSION(PK)|NAME|KEY|PARENT_KEY|DIST_KEY(FK)|
+-----------+----+---+----------+------------+
|1 |a |12 |NULL |1 |
+-----------+----+---+----------+------------+
|2 |b |13 |12 |1 |
+-----------+----+---+----------+------------+
|3 |c |14 |13 |1 |
+-----------+----+---+----------+------------+
|4 |d |15 |12 |1 |
+-----------+----+---+----------+------------+
|5 |e |16 |NULL |1 |
+-----------+----+---+----------+------------+
|6 |e |17 |NULL |2 |
+-----------+----+---+----------+------------+
Nach der Aktualisierung der Zeile muss der übergeordnete Schlüssel des Elements überprüft werden, damit das Element nicht selbstgroß oder etwas sein kann.
Und wenn ich die Zeile lösche, muss ich alle Kinder und Kinder von Kindern usw. löschen.
Fragen sind:
Wie kann ich alle "Eltern + Großeltern + usw." eines Elements von DIST auswählen?
Wie kann ich alle "Söhne + Enkel + etc" eines Elements von DIST auswählen?
Ich habe über Lösungen mit CTE gelesen, aber ich habe keine Wurzel von Elementen und ich kann nicht einmal verstehen, wie ich CTE dann verwenden kann.
Bitte helfen
Vielen Dank.
Ich bin diesem Problem begegnet
--all "parent + grandparent + etc" @childID Replaced with the ID you need
with tbParent as
(
select * from Elem where [KEY][email protected]
union all
select Elem.* from Elem join tbParent on Elem.[KEY]=tbParent.PARENT_KEY
)
SELECT * FROM tbParent
--all "sons + grandsons + etc" @parentID Replaced with the ID you need
with tbsons as
(
select * from Elem where [KEY][email protected]
union all
select Elem.* from Elem join tbsons on Elem.PARENT_KEY=tbsons.[KEY]
)
SELECT * FROM tbsons
PS.Mein Englisch ist nicht gut.
hier ist eine rekursive Abfrage, die alle Vorfahren und Nachkommen eines Elements enthält. Verwenden Sie diese zusammen oder trennen Sie sie je nach Situation. Ersetzen Sie die where-Klauseln, um den gewünschten Datensatz zu erhalten. In diesem Beispiel suche ich nach Schlüssel 13 (dies ist das Element mit name = b) und finde seinen Vorfahren 12/a und seinen Nachkommen 14/c.
with all_ancestors(relation, version, name, elem_key, parent_key, dist_key)
as
(
-- the record itself
select 'self ' as relation, self.version, self.name, self.elem_key, self.parent_key, self.dist_key
from elem self
where elem_key = 13
union all
-- all its ancestors found recursively
select 'ancestor ' as relation, parent.version, parent.name, parent.elem_key, parent.parent_key, parent.dist_key
from elem parent
join all_ancestors child on parent.elem_key = child.parent_key
)
, all_descendants(relation, version, name, elem_key, parent_key, dist_key)
as
(
-- the record itself
select 'self ' as relation, self.version, self.name, self.elem_key, self.parent_key, self.dist_key
from elem self
where elem_key = 13
union all
-- all its descendants found recursively
select 'descendant' as relation, child.version, child.name, child.elem_key, child.parent_key, child.dist_key
from elem child
join all_descendants parent on parent.elem_key = child.parent_key
)
select * from all_ancestors
union
select * from all_descendants
order by elem_key
;
Hier ist die SQL-Geige: http://sqlfiddle.com/#!6/617ee/28 .
Ich habe eine Funktion zum Finden der Eltern eines bestimmten Kindes erstellt, bei der Sie die ID des Kindes übergeben müssen.
Dadurch wird die Liste der Eltern als durch Kommas getrennte Zeichenfolge zurückgegeben. Versuchen Sie dies, wenn es für Sie funktioniert.
Ich gehe davon aus, dass der parent_key with null value
root ist.
CREATE FUNCTION checkParent(@childId INT)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @parentId VARCHAR(MAX) = NULL
DECLARE @parentKey INT = null
SET @parentId = (SELECT parent_key FROM Elem WHERE [KEY] = @childId)
WHILE(@parentKey IS NOT NULL)
begin
SET @parentId = @parentId + ', ' + (SELECT parent_key FROM Elem WHERE [KEY] = @parentId)
SET @parentKey = (SELECT parent_key FROM Elem WHERE [KEY] = @parentId)
END
RETURN @parentId
END
GO
Ich glaube nicht, dass dies in einem einzigen Fall in einem einzigen Fall ausgeführt werden kann, sodass Sie alle Eltern, Großeltern, ... auswählen können. Eine Möglichkeit, dies zu tun, besteht darin, den elem-Tisch mit sich selbst zu verbinden, und es hängt davon ab, wie viele Ebenen Sie beitreten, wie viele Kinder, Enkelkinder.
Die Lösung kann so etwas sein (für den zweiten Fall)
dadurch werden alle Eltern, Kinder und Enkelkinder ausgewählt
Select
parent.key as parent_key,
child.key as child_key,
grandchild.key as grandchild_key
from elem parent
join elem child on (elem.key=child.parentkey)
join elem grandchild on (child.key=grandchild.parentkey)
where parent.parentkey is null; -- this make you sure that first level will be parents
lösung für den ersten Fall ist nur, dass Sie Tabellen nicht im Stil von 'key = parentkey', sondern gegenüber 'parentkey = key' verbinden.