sagen, dass ich einen Start Tabelle haben (abgeleitet), die wie das ist ...mysql rekursive selbst verbinden sich schneidende Spalten
-------------------------------------------------------
| UsergroupID | ParentID | PermissionIDs |
-------------------------------------------------------
| 1 | 0 | 1 |
| 1 | 0 | 2 |
| 1 | 0 | 3 |
| 1 | 0 | 4 |
| 1 | 0 | 5 |
| 1 | 0 | 6 |
| 2 | 1 | 1 |
| 2 | 1 | 8 |
| 2 | 1 | 9 |
| 3 | 1 | 3 |
| 3 | 1 | 8 |
| 3 | 1 | 2 |
-------------------------------------------------------
und ich suche eine End-Ergebnismenge zu erhalten, die
wie folgt aussieht-------------------------------------------------------
| UsergroupID | ParentID | PermissionID |
-------------------------------------------------------
| 1 | 0 | 1 |
| 1 | 0 | 2 |
| 1 | 0 | 3 |
| 1 | 0 | 4 |
| 1 | 0 | 5 |
| 1 | 0 | 6 |
| 2 | 1 | 1 |
| 3 | 1 | 3 |
| 3 | 1 | 2 |
-------------------------------------------------------
, die im Grunde eine rekursive Suche auf der übergeordneten ID und dann schneiden (innere Verbindung) die Werte in der PermissionID Spalte. Ein Kind kann also nie mehr Berechtigungen als ein Elternteil haben.
Ich habe Sachen auf benutzerdefinierten Funktionen nachgeschlagen (ich denke, ich könnte ein PDF um eine Spalte wickeln und es rekursiv schneiden basierend auf einer Eltern-ID), aber das brachte mich nicht sehr weit. Das einzige, woran ich wirklich denken kann, ist, es nicht db-Seite zu tun, sondern mit serverseitigem Code.
Solarflare - Hier ist, was ich gerade mit Ihrem Skript versucht habe ... das hat funktioniert!
delimiter $$
CREATE PROCEDURE prcPermCleanup5()
BEGIN
DROP TABLE IF EXISTS table1;
CREATE TABLE table1 (usergroupID INT, parentID INT, StoreID INT) ENGINE=MEMORY;
INSERT INTO table1 VALUES
(1,0,1),
(1,0,2),
(1,0,3),
(1,0,4),
(2,1,1),
(2,1,2),
(2,0,5),
(3,2,2),
(3,2,7),
(4,1,1),
(4,1,2),
(5,4,1),
(5,4,8),
(6,2,1),
(6,2,6);
REPEAT
DELETE entry.*
FROM table1 entry
LEFT JOIN table1 parent
ON entry.parentID = parent.usergroupID
AND entry.`StoreID` = parent.StoreID
WHERE parent.usergroupID IS NULL
AND NOT entry.parentID = 0;
UNTIL row_count() = 0 END REPEAT;
SELECT * FROM table1;
END $$
delimiter ;
Sind Sie öffnen Ihre Daten zu normalisieren und haben nicht ein Array von Berechtigungen in der Spalte BerechtigungenID und verwenden Sie stattdessen eine andere Tabelle, die diese Berechtigungen auflistet? Die meisten Probleme werden mit unnormalisierten Daten komplizierter, das ist ein gutes Beispiel. Und möglicherweise möchten Sie verschachtelte Mengen verwenden, obwohl Sie wahrscheinlich auch die Struktur verwenden können (wenn Sie Ihre Funktion für die Rekursion wiederholen) – Solarflare
Ich bin offen für die Änderung des Datenformats und meines zweiten Tabellenbeispiels (3. Tabelle im ursprünglichen Beitrag) ist eine, die die Berechtigungen als Zeilen und nicht als eine verkettete Spalte anzeigt. Diese "Tabelle" ist auch eine abgeleitete Tabelle. – Josh
Ah ok, ja, das ist besser, ich glaube, ich habe den Punkt des "Starttisches" verpasst. Sie haben also Ihre Tabelle: Möchten Sie "aufräumen" (löschen oder markieren Sie die "falschen" Einträge) oder möchten Sie die "falschen" Einträge behalten und eine Abfrage haben, die diese sauberere Liste zurückgibt? Ich denke, beides kann nicht in einem einzigen Schritt gemacht werden, aber der erste wäre eine Abfrage, die du n-mal ausführen müsstest (n = Tiefe deines Baumes - 1 oder bis sich nichts ändert), der zweite würde, denke ich, eine temporäre Tabelle benötigen (Sie können dies in einer gespeicherten Prozedur/udf tun). – Solarflare