Frage gestellt
Das können Sie nicht einen Tabellenalias referenzieren von einer Unterabfrage in einer anderen Abfrage auf der gleichen Ebene (oder in einem anderen Zweig einer UNION
Anfrage). Ein Tabellenalias ist nur in der Abfrage selbst und Unterabfragen davon sichtbar.
Sie könnten Verweisen Sie auf Ausgabespalten einer Unterabfrage auf derselben Abfrageebene mit einem LATERAL JOIN
. Beispiel:
Finden Sie die häufigsten Elemente in einem Array mit einer Gruppierung nach
Lösung für kleine maximale Levelanzahl
Für nur eine Handvoll Level (wenn Sie wissen das Maximum), können Sie eine einfache Abfrage verwenden:
LEFT JOIN
auf n-1 Instanzen der Tabelle selbst- Verwenden Sie
COALESCE
und einCASE
Anweisung, um die Wurzel und die Höhe festzulegen,
SELECT p1.c AS child, COALESCE(p3.p, p2.p, p1.p) AS parent
,CASE
WHEN p3.p IS NOT NULL THEN 3
WHEN p2.p IS NOT NULL THEN 2
ELSE 1
END AS height
FROM parent p1
LEFT JOIN parent p2 ON p2.c = p1.p
LEFT JOIN parent p3 ON p3.c = p2.p
WHERE p1.c IN (3, 8)
ORDER BY p1.c;
Dies ist Standard-SQL und sollte in allen 4 RDBMS funktionieren du getaggt hast.
Generische Lösung für beliebig viele Ebenen
Verwenden Sie einen rekursiven CTE wie @Ken bereits empfohlen hat.
- Im rekursiven Bein behalte das Kind für jede Zeile nur das übergeordnete Element vorrücken.
- Im äußeren
SELECT
, behalten Sie nur die Zeile mit der größtenheight
pro Kind.
WITH RECURSIVE cte AS (
SELECT c AS child, p AS parent, 1 AS height
FROM parent
WHERE c IN (3, 8)
UNION ALL
SELECT c.child, p.p AS parent, c.height + 1
FROM cte c
JOIN parent p ON p.c = c.parent
-- WHERE c.height < 10 -- to safeguard against endless loops if necessary
)
SELECT DISTINCT ON (child) *
FROM cte
ORDER BY child, height DESC;
DISTINCT ON
ist spezifisch für Postgres . Erklärung:
Erste Zeile in jeder GROUP BY-Gruppe auswählen?
Der Rest würde in Oracle auf ähnliche Weise funktionieren und sogar SQLite , aber nicht in MySQL, das CTEs nicht unterstützt.
SQL-Fiddle demonstriert beides.