Vraag gesteld
Je kan niet verwijzen naar een tabelalias van de ene subquery in een andere query op hetzelfde niveau (of in een ander deel van een UNION
vraag). Een tabelalias is alleen zichtbaar in de query zelf en subquery's ervan.
U zou referentie-uitvoerkolommen van een subquery op hetzelfde queryniveau met een LATERAL JOIN
. Voorbeeld:
Vind de meest voorkomende elementen in een array met een groep op
Oplossing voor een klein maximum aantal niveaus
Voor slechts een handvol niveaus (als je weet het maximum), kunt u een eenvoudige zoekopdracht gebruiken:
LEFT JOIN
tot n-1 instanties van de tabel zelf- Gebruik
COALESCE
en eenCASE
statement om de wortel en hoogte vast te pinnen,
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;
Dit is standaard SQL en zou in alle 4 RDBMS moeten werken je hebt getagd.
Algemene oplossing voor willekeurig aantal niveaus
Gebruik een recursieve CTE zoals @Ken al heeft geadviseerd.
- In het recursieve been het kind houden voor elke rij, alleen de ouder vooruit.
- In de buitenste
SELECT
, bewaar alleen de rij met de grootsteheight
per 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
is specifiek voor Postgres . Uitleg:
Selecteer de eerste rij in elke GROUP BY-groep?
De rest zou op een vergelijkbare manier werken in Oracle en zelfs SQLite , maar niet in MySQL die geen CTE's ondersteunt.
SQL Fiddle beide demonstreren.