Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Gunakan alias tabel dalam kueri lain untuk melintasi pohon

Pertanyaan diajukan

Anda tidak bisa referensikan alias tabel dari satu subkueri di kueri lain pada level yang sama (atau di bagian lain dari UNION pertanyaan). Alias ​​tabel hanya terlihat dalam kueri itu sendiri dan subkuerinya.
Anda bisa referensi kolom keluaran subkueri pada tingkat kueri yang sama dengan LATERAL JOIN . Contoh:
Temukan elemen paling umum dalam larik dengan grup menurut

Solusi untuk jumlah level maksimum yang kecil

Hanya untuk beberapa level (jika Anda tahu maksimum), Anda dapat menggunakan kueri sederhana:

  • LEFT JOIN ke n-1 instance dari tabel itu sendiri
  • Gunakan COALESCE dan CASE pernyataan untuk menentukan akar dan tinggi,
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;

Ini adalah SQL standar dan harus bekerja di semua 4 RDBMS Anda menandai.

Solusi umum untuk jumlah level yang berubah-ubah

Gunakan CTE rekursif seperti @Ken sudah disarankan.

  • Di kaki rekursif pertahankan anak untuk setiap baris, hanya memajukan induknya.
  • Di bagian luar SELECT , hanya simpan baris dengan height terbesar per anak.
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 khusus untuk Postgres . Penjelasan:
Pilih baris pertama di setiap grup GROUP BY?

Sisanya akan bekerja dengan cara yang sama di Oracle dan bahkan SQLite , tetapi tidak di MySQL yang tidak mendukung CTE.

SQL Fiddle mendemonstrasikan keduanya.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kesalahan Perbandingan PL/SQL di pemicu (PLS-00405)

  2. REGEXP_INSTR() Fungsi di Oracle

  3. Ubah VARCHAR2 menjadi Angka

  4. Prosedur Tersimpan Oracle dan tipe data khusus

  5. Oracle SEQUENCE.Masalah Currval di CodeIgniter