2012-02-26 44 views
5

Tôi không chắc liệu cơ sở dữ liệu SQL Server có thể thực hiện điều đó không?Tôi có thể thực hiện SELECT đệ quy trong cơ sở dữ liệu T-SQL

Nói, tôi có một bảng:

id INT 
nm NVARCHAR(256) 
cid INT --references [id] 

và dữ liệu giả:

id nm  cid 
1 Name 1 0 
2 Name 2 0 
3 Name 3 1 
4 Name 4 3 
5 Name 5 2 
6 Name 6 4 
7 Name 7 2 

Và logic để lựa chọn nên là như sau:

  1. Này, chúng ta có id gốc, hãy gọi nó là N.

  2. Sau đó, chúng tôi có một id tra cứu, chúng ta hãy gọi nó là X. Sau đó, chúng tôi làm:

    SELECT [cid] FROM [TableName] WHERE [id]=X 
    

và kiểm tra nếu kết quả là bằng N. Nếu có, thì chúng ta trở lại [nm] cho rằng kỷ lục . Nếu kết quả là 0, thì chúng ta trả về Null. Nếu kết quả là một cái gì đó khác chúng ta làm cùng một lựa chọn, ngoại trừ X bây giờ là giá trị kết quả.

Tôi rõ ràng có thể làm điều này với C# nhưng tôi tò mò nếu như vậy có thể kết thúc trong một câu lệnh SQL thuần túy?

PS. Chỉ để minh họa điều này với bàn của tôi ở trên, nếu N là 1 và X là 6, sau đó chúng tôi nhận được:

SELECT [cid] FROM [TableName] WHERE [id]=6 --results is 4 (not N or 0, then continue) 
SELECT [cid] FROM [TableName] WHERE [id]=4 --results is 3 (not N or 0, then continue) 
SELECT [cid] FROM [TableName] WHERE [id]=3 --results is 1 (is N, then return "Name 1") 

hoặc nếu N là 1 và X là 7, chúng tôi nhận được:

SELECT [cid] FROM [TableName] WHERE [id]=7 --results is 2 (not N or 0, then continue) 
SELECT [cid] FROM [TableName] WHERE [id]=2 --results is 0 (is 0, then return Null) 

EDIT: Tôi cần điều này để chạy trong SQL Server 2008.

+0

DBMS của bạn là gì? SQL Server, Oracle, hoặc những người khác? –

+1

Phiên bản SQL Server nào? Điều này là có thể với CTE đệ quy (biểu thức bảng chung), nhưng tôi không biết liệu chúng có sẵn trên phiên bản của bạn không. – hvd

+0

@hvd Tôi đang sử dụng SQL Server 2008 – ahmd0

Trả lời

14

CTE đệ quy có thể thực hiện việc này. Nó sẽ giống như thế này:

WITH q AS (
    SELECT t.id, t.name, t.cid 
    FROM t 
    WHERE t.id = @x 
    UNION ALL 
    SELECT t.id, t.name, t.cid 
    FROM q 
    INNER JOIN t 
    ON t.id = q.cid 
) 
SELECT name 
FROM q 
WHERE id = @n 

Ý tưởng là một CTE có thể tham khảo chính nó trong phần thứ hai của một điều khoản UNION ALL, và nó sẽ đánh giá phần thứ hai cho đến khi nó tạo ra không có kết quả hơn, hoặc một giới hạn nội bộ đạt được.

+0

Rất đẹp. Tôi cần phải thử nó. Cảm ơn. – ahmd0

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