Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Sử dụng bí danh bảng trong một truy vấn khác để duyệt qua một cây

Câu hỏi được đặt ra

Bạn không thể tham chiếu một bí danh bảng từ một truy vấn con trong một truy vấn khác ở cùng cấp độ (hoặc trong một phần khác của UNION truy vấn). Bí danh bảng chỉ hiển thị trong chính truy vấn và các truy vấn phụ của nó.
Bạn có thể tham chiếu các cột đầu ra của truy vấn con ở cùng cấp truy vấn với LATERAL JOIN . Ví dụ:
Tìm các phần tử phổ biến nhất trong mảng với một nhóm theo

Giải pháp cho số cấp tối đa nhỏ

Chỉ dành cho một số cấp độ (nếu bạn biết tối đa), bạn có thể sử dụng một truy vấn đơn giản:

  • LEFT JOIN đến n-1 phiên bản của chính bảng
  • Sử dụng COALESCECASE câu lệnh ghim root và hight,
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;

Đây là SQL tiêu chuẩn và sẽ hoạt động trong cả 4 RDBMS bạn đã gắn thẻ.

Giải pháp chung cho số cấp tùy ý

Sử dụng CTE đệ quy như @Ken đã tư vấn.

  • Trong chân đệ quy, giữ con đối với mỗi hàng, chỉ nâng cấp hàng chính.
  • Trong SELECT bên ngoài , chỉ giữ một hàng có height lớn nhất mỗi đứa trẻ.
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 dành riêng cho Postgres . Giải thích:
Chọn hàng đầu tiên trong mỗi GROUP BY nhóm?

Phần còn lại sẽ hoạt động theo cách tương tự trong Oracle và thậm chí cả SQLite , nhưng không phải trong MySQL không hỗ trợ CTE.

SQL Fiddle thể hiện cả hai.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Máy chủ Sql tương đương với DBMS_ASSERT của Oracle là gì?

  2. Oracle CHỌN 10 bản ghi hàng đầu

  3. Làm thế nào để liên kết một người dùng với nhiều lược đồ của một cơ sở dữ liệu?

  4. PL / SQL Cursor cho vòng lặp

  5. REGEX để chọn giá trị thứ n từ danh sách, cho phép các giá trị rỗng