2010-10-14 37 views
6

đầu tiên tôi phải thừa nhận rằng tôi không quen thuộc với máy chủ sql recursive CTE's nhưng tôi nghĩ đây là cách tiếp cận tốt nhất.CTE đệ quy để tìm hồ sơ gốc

Tôi có một bảng tabData. PK của nó có tên là idData và có tự tham chiếu FK fiData.

Schema

Vì vậy fiData tham chiếu các bản ghi phụ huynh và SELECT * FROM tabData WHERE idData=fiData trả về tất cả dữ liệu của công ty mẹ. Điều này rất đơn giản và nhanh chóng. Nhưng làm thế nào để có được tất cả các bậc cha mẹ từ một hồ sơ nhất định theo thứ tự tự nhiên? Giả sử có một đứa trẻ (idData = 4) với 3 cha mẹ (cha mẹ đầu tiên là kỷ lục với idData = 3):

idData fiData 
4   3  
3   2  
2   1  
1   NULL  

Tôi nghĩ đệ quy CTE là con đường để đi, nhưng tôi không nhận được cùng tốt với cú pháp của nó. Vì vậy, cách chính xác để thực hiện CTE là gì sẽ trả về tất cả các bậc cha mẹ?

tôi đã cố gắng sau, nhưng nó mang lại cho tôi những kết quả sai (3,4 thay vì 3,2,1): (Để kiểm tra nó tôi đã tạo ra một bảng tạm thời đối với tôi và bạn)

IF (NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'tabData_Temp')) 
BEGIN 
CREATE TABLE [dbo].[tabData_Temp](
    [idData] [int] NOT NULL, 
    [fiData] [int] NULL, 
    CONSTRAINT [PK_tabData_Temp] PRIMARY KEY CLUSTERED 
    (
    [idData] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
); 

ALTER TABLE [dbo].[tabData_Temp] WITH CHECK ADD CONSTRAINT [FK_tabData_Temp] FOREIGN KEY([fiData]) 
REFERENCES [dbo].[tabData_Temp] ([idData]); 
ALTER TABLE [dbo].[tabData_Temp] CHECK CONSTRAINT [FK_tabData_Temp]; 

INSERT INTO [dbo].[tabData_Temp](idData,fiData)VALUES(1,NULL); 
INSERT INTO [dbo].[tabData_Temp](idData,fiData)VALUES(2,1); 
INSERT INTO [dbo].[tabData_Temp](idData,fiData)VALUES(3,2); 
INSERT INTO [dbo].[tabData_Temp](idData,fiData)VALUES(4,3); 
END 

/* here comes the (not working) recursive CTE */ 
Declare @fiData int; 
SET @fiData = 3; 
WITH PreviousClaims(idData,fiData) 
AS(
    SELECT parent.idData,parent.fiData 
    FROM tabData_temp parent 
    WHERE parent.idData = @fiData 

    UNION ALL 

    SELECT child.idData,child.fiData 
    FROM tabData_temp child 
    INNER JOIN PreviousClaims parent ON parent.idData = child.fiData 
) 
SELECT idData 
FROM PreviousClaims; 
/* end of recursive CTE */ 


DROP TABLE [dbo].[tabData_Temp]; 

Cảm ơn bạn trước.

Trả lời

7

Thay đổi để:

INNER JOIN PreviousClaims parent ON parent.fiData = child.idData 

Đã cho tôi những kết quả bạn muốn.

+2

Cảm ơn này, tôi đã rất gần;) –

6

Bạn có tham gia lạc hậu.

Thay đổi này

INNER JOIN PreviousClaims parent ON parent.idData= child.fiData 

để

INNER JOIN PreviousClaims parent ON parent.fiData = child.idData 
+0

Cảm ơn, Kirk Woll là vài giây nhanh hơn. –

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