Ich habe eine Oracle 12c Datenbank mit einer Tabelle mit baumartiger Struktur für Organisationseinheiten (Abteilungen und so weiter):SQL-Abfrage zurück entsprechende Datensätze mit ihren Vorfahren in baumartiger Struktur
CREATE TABLE "OUS" (
"ID" NUMBER(38,0) NOT NULL ENABLE,
"NAME" VARCHAR2(255 CHAR) NOT NULL ENABLE,
"PARENT_ID" NUMBER(38,0),
PRIMARY KEY("ID"),
CONSTRAINT "OUS_HIERARCHY_FK" FOREIGN KEY ("PARENT_ID") REFERENCES "OUS" ("ID") ON DELETE CASCADE
);
So, mit der Struktur wie
| id | name | parent_id |
| -: | ------------- | --------: |
| 1 | Root | (NULL) |
| 2 | Territorial 1 | 1 |
| 3 | Regional 1-1 | 2 |
| 4 | Alpha dept | 3 |
| 5 | Beta dept | 3 |
| 6 | Regional 1-2 | 2 |
| 7 | Gamma dept | 6 |
| 8 | Delta dept | 7 |
| 9 | Territorial 2 | 1 |
| 10 | Regional 2-1 | 9 |
| 11 | Epsilon dept | 10 |
| 12 | Zeta dept | 10 |
Sie können es schaffen mit SQL wie:
INSERT INTO ous (id, name, parent_id) VALUES (13, 'Root', NULL);
INSERT INTO ous (id, name, parent_id) VALUES ( 2, 'Territorial 1', 13);
INSERT INTO ous (id, name, parent_id) VALUES ( 1, 'Regional 1-1', 2);
INSERT INTO ous (id, name, parent_id) VALUES ( 5, 'Alpha dept', 1);
INSERT INTO ous (id, name, parent_id) VALUES ( 4, 'Beta dept', 1);
INSERT INTO ous (id, name, parent_id) VALUES ( 6, 'Regional 1-2', 2);
INSERT INTO ous (id, name, parent_id) VALUES ( 7, 'Gamma dept', 6);
INSERT INTO ous (id, name, parent_id) VALUES ( 8, 'Delta dept', 6);
INSERT INTO ous (id, name, parent_id) VALUES ( 9, 'Territorial 2', 13);
INSERT INTO ous (id, name, parent_id) VALUES ( 3, 'Regional 2-1', 9);
INSERT INTO ous (id, name, parent_id) VALUES (15, 'Epsilon dept', 3);
INSERT INTO ous (id, name, parent_id) VALUES (12, 'Zeta dept', 3);
Ich muss einige der Organisationseinheiten finden, die bestimmte Kriterien erfüllen (wie name = 'Alpha' OR name = 'Epsilon
) und einen Teilbaum dieser OU und ihrer Vorfahren erhalten.
Zum Beispiel:
| id | name | parent_id |
| -: | ------------- | --------: |
| 1 | Root | (NULL) | ← Ancestor of Alpha and Epsilon
| 2 | Territorial 1 | 1 | ← Ancestor of Alpha
| 3 | Regional 1-1 | 2 | ← Ancestor of Alpha
| 4 | Alpha dept | 3 | ← Matches the WHERE clause!
| 9 | Territorial 2 | 1 | ← Ancestor of Epsilon
| 10 | Regional 2-1 | 9 | ← Ancestor of Epsilon
| 11 | Epsilon dept | 10 | ← Matches the WHERE clause!
ich an verschiedenen Hierarchical and recursive queries in SQL sah: Oracle Hierarchical queries und CTEs, kann aber nicht eine Abfrage herausfinden, die mir ein solches Ergebnis zurückgeben kann.
Ich verwende Oracle Database 12c.
Ich habe versucht, Anfragen wie:
SELECT ous.* FROM ous
WHERE name = 'Alpha' OR name = 'Epsilon'
START WITH
parent_id IS NULL
CONNECT BY
PRIOR id = parent_id
ORDER SIBLINGS BY name;
Aber es gibt 0 Zeilen wie WHERE auf alle Zeilen angewendet wird (so Vorfahren gefiltert werden)
Auch habe ich versucht:
WITH RECURSIVE all_nodes (id, parent_id, name) AS (
SELECT ous.id, ous.parent_id, name FROM ous WHERE (name = 'Alpha' OR name = 'Epsilon')
UNION
SELECT ous.id, ous.parent_id, name FROM ous INNER JOIN all_nodes ON ous.parent_id = all_nodes.id
)
SELECT * FROM all_nodes INNER JOIN ous ON all_nodes.id = ous.id ORDER BY name;
Aber es gibt Fehler SQL Error [905] [42000]: ORA-00905: keyword is missing
Vielen Dank für die schnelle Antwort. Leider gibt Ihre Abfrage nur übereinstimmende Zeilen ohne ihre Vorfahren zurück. Auch Oracle sagt, dass rekursive CTE eine Alias-Liste (ORA-32039) haben muss, also habe ich die erste Zeile in 'mit t (name, id, parent_id) als (') geändert. – Envek
Es wurde herausgefunden: die Gleichheit in ON-Klausel sollte umgekehrt werden: auf ous.id = t.parent_id. Jetzt funktioniert es! – Envek
Ist es möglich, die Ergebnisse nach Hierarchie und Namen zu sortieren, falls die IDs nicht von Eltern zu Kindern wachsen, wie zB ORDER SIBLINGS BY in der Oracle-Syntax? – Envek