sql >> Database teknologi >  >> RDS >> Oracle

Brug tabelalias i en anden forespørgsel til at krydse et træ

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 en CASE 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ørste height 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.



  1. valgt værdi få fra db til dropdown vælg boks mulighed ved hjælp af php mysql fejl

  2. Hvordan omdøber jeg en fremmednøgle i mysql?

  3. SQL Server AlwaysOn ( Tilgængelighedsgruppe ) arkitektur og trin for trin installation - 3 Manuel fejl over trin

  4. Er der en MD5 Sum funktion i PL/SQL