2010-08-12 79 views
11

Tôi có một bảng:Làm thế nào để tự JOIN đệ quy trong SQL?

 
Series 
======== 
ID 
SeriesName 
ParentSeriesID 

Một loạt có thể là một "gốc" series, (ParentSeriesID là 0 hoặc null) hoặc nó có thể có một phụ huynh. Một chuỗi cũng có thể là một vài cấp độ xuống, tức là Cha mẹ của nó có Phụ huynh, có Phụ huynh, v.v.

Làm cách nào để truy vấn bảng lấy Series bằng ID của nó và TẤT CẢ chuỗi hậu duệ '?

Cho đến nay tôi đã cố gắng:

SELECT child.* 
FROM Series parent JOIN Series child ON child.ParentSeriesID = parent.ID 
WHERE parent.ID = @ParentID 

Nhưng điều này chỉ trả về cấp độ đầu tiên của trẻ em, tôi muốn nút phụ huynh, và tất cả các nút "hạ lưu". Tôi không chắc chắn làm thế nào để tiến bộ từ đây.

Trả lời

13

Nếu bạn đang sử dụng SQL Server 2005 +, bạn có thể sử dụng các biểu thức bảng chung

With Family As 
( 
Select s.ID, s.ParentSeriesId, 0 as Depth 
From Series s 
Where ID = @ParentID 
Union All 
Select s2.ID, s2.ParentSeriesId, Depth + 1 
From Series s2 
    Join Family 
     On Family.ID = s2.ParentSeriesId 
) 
Select * 
From Family 

Để biết thêm:

Recursive Queries Using Common Table Expressions

+0

Tôi đã sửa đổi truy vấn của bạn để làm cho nó hoạt động, đặt nó trong chỉnh sửa của tôi cho câu hỏi của bạn. Cảm ơn bạn đã giúp đỡ! –

+0

Bất kỳ cách nào để làm điều này trên một máy chủ db sql không MS? Tôi cần một cách tiêu chuẩn hơn mà không cần sử dụng CTE. –

+0

@goku_da_master - Tùy thuộc vào ý của bạn. Cùng một mã sẽ hoạt động tốt trên Postgres, Oracle và DB2. Các biểu thức bảng chung là một phần của đặc tả SQL và do đó được thực hiện bởi nhiều nhà cung cấp. Tuy nhiên, có vẻ như bạn đang yêu cầu làm thế nào để đạt được cùng trên một cơ sở dữ liệu không hỗ trợ CTE như MySQL hoặc MS Access. Câu trả lời sẽ tùy thuộc vào sản phẩm. – Thomas

2

Make sử dụng các tính năng CTE avaiable trong máy chủ SLQ 2005 trở đi cho truy vấn recurisve

USE AdventureWorks 
GO 
WITH Emp_CTE AS (
SELECT EmployeeID, ContactID, LoginID, ManagerID, Title, BirthDate 
FROM HumanResources.Employee 
WHERE ManagerID IS NULL 
UNION ALL 
SELECT e.EmployeeID, e.ContactID, e.LoginID, e.ManagerID, e.Title, e.BirthDate 
FROM HumanResources.Employee e 
INNER JOIN Emp_CTE ecte ON ecte.EmployeeID = e.ManagerID 
) 
SELECT * 
FROM Emp_CTE 
GO 

Bạn có thể xem ví dụ ở đây:

SQL SERVER – Simple Example of Recursive CTE

+0

CTE? Tôi có SQL 2005 –

+2

cte = biểu thức bảng chung! – SwissCoder

5

Tôi chỉ tăng cường công tác Thomas. Nếu bạn cần phải có chiều sâu của hệ thống phân cấp và nhận được parentid ở đây là mã.

Đây là gần như giống với công việc của Thomas.

With Family As 
( 
    Select s.ID, s.ParentSeriesId, 0 as Depth 
    From Series s 
    Where ID = @ParentID <--- this was removed if you intend to get all hierarchy of the record. You can retain this if you want 
    Union All 
    Select s2.ID, s2.ParentSeriesId < --- change to **Family.ParentID**, Depth + 1 
    From Series s2 
    Join Family 
     On Family.ID = s2.ParentSeriesId 
) 
Select * 
From Family 

Đó là tất cả. Tôi biết đã quá muộn nhưng tôi hy vọng bất kỳ ai gặp phải điều này đều có thể giúp họ. Cảm ơn Thomas cho mã ban đầu. :)

Các vấn đề liên quan