Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Użyj aliasu tabeli w innym zapytaniu, aby przejść przez drzewo

Zadane pytanie

nie możesz odwołać się do aliasu tabeli z jednego podzapytania w innym zapytaniu na tym samym poziomie (lub w innej gałęzi UNION zapytanie). Alias ​​tabeli jest widoczny tylko w samym zapytaniu i jego podzapytaniach.
Możesz mógł odwołaj się do kolumn wyjściowych podzapytania na tym samym poziomie zapytania z LATERAL JOIN . Przykład:
Znajdź najczęstsze elementy w tablicy z grupą według

Rozwiązanie dla małej maksymalnej liczby poziomów

Tylko dla kilku poziomów (jeśli wiesz maksimum), możesz użyć prostego zapytania:

  • LEFT JOIN do n-1 instancji samej tabeli
  • Użyj COALESCE i CASE oświadczenie określające korzeń i wysokość,
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;

To jest standardowy SQL i powinien działać we wszystkich 4 RDBMS oznaczyłeś.

Ogólne rozwiązanie dla dowolnej liczby poziomów

Użyj rekurencyjnego CTE jak już radził @Ken.

  • W odnodze rekurencyjnej trzymaj dziecko dla każdego rzędu przesuwaj tylko rodzica.
  • W zewnętrznym SELECT , zachowaj tylko wiersz o największej height na dziecko.
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 jest specyficzny dla Postgresu . Wyjaśnienie:
Wybrać pierwszy wiersz w każdej grupie GROUP BY?

Reszta działałaby w podobny sposób w Oracle a nawet SQLite , ale nie w MySQL, który nie obsługuje CTE.

Skrzypce SQL demonstrując oba.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak zaimplementowano limit czasu zapytania JDBC firmy Oracle?

  2. Jak przekazać cały wiersz (w SQL, nie PL/SQL) do funkcji przechowywanej?

  3. Trzeba zresetować wartość sekwencji w Oracle

  4. Witryna niedostępna i kanał na Twitterze

  5. spraw, aby optymalizator używał wszystkich kolumn indeksu