Spørgsmålet stillet
Du kan ikke henvise til et tabelalias fra én underforespørgsel i en anden forespørgsel på samme niveau (eller i en anden del af en UNION
forespørgsel). Et tabelalias er kun synligt i selve forespørgslen og underforespørgsler til den.
Du kunne reference outputkolonner for en underforespørgsel på samme forespørgselsniveau med en LATERAL JOIN
. Eksempel:
Find de mest almindelige elementer i array med en gruppe ved at
Løsning til et lille maksimalt antal niveauer
For kun en håndfuld niveauer (hvis du ved det maksimum), kan du bruge en simpel forespørgsel:
LEFT JOIN
til n-1 forekomster af selve tabellen- Brug
COALESCE
og enCASE
sætning for at fastgøre roden og højden,
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;
Dette er standard SQL og burde fungere i alle 4 RDBMS du taggede.
Generisk løsning til vilkårligt antal niveauer
Brug en rekursiv CTE som @Ken allerede har anbefalet.
- I det rekursive ben hold barnet for hver række skal du kun gå videre til forælderen.
- I den ydre
SELECT
, behold kun rækken med den størsteheight
pr. barn.
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
er specifik for Postgres . Forklaring:
Vælg første række i hver GROUP BY-gruppe?
Resten ville fungere på lignende måde i Oracle og endda SQLite , men ikke i MySQL, som ikke understøtter CTE'er.
SQL Fiddle demonstrerer begge dele.