2016-08-09 49 views
1

我有下面的記錄集,我試圖從給定的父ID得到鏈接ID的列表。TSQL遞歸CTE - 獲取子女記錄ID至某一點

DECLARE @TableVals TABLE 
        ([ID] NVARCHAR(5), 
        [NewId] NVARCHAR(5), 
        [LinkDate] DATETIME, 
        [IsUnlink] BIT); 

INSERT INTO @TableVals 
VALUES ('00899', '00897', '01 Jan 2012 13:46:30', 0), 
     ('00900', '00903', '01 Jan 2012 12:05:16', 0), 
     ('00901', '00903', '01 Jan 2012 11:03:13', 1), 
     ('00903', '00897', '01 Jan 2012 11:01:57', 0), 
     ('00902', '00903', '01 Jan 2012 10:44:00', 0), 
     ('00898', '00906', '01 Jan 2012 10:34:36', 1), 
     ('00895', '00897', '01 Jan 2012 10:25:51', 0), 
     ('00893', '00897', '01 Jan 2012 10:25:33', 0), 
     ('00891', '00897', '01 Jan 2012 10:24:48', 0) 

我有這種CTE其返回兩個意外的值(0090000902),因爲這些被鏈接到00903這是從解除鏈接。我試圖在LinkDate上進行檢查,但我懷疑我沒有把它做得很正確。

DECLARE @ID NVARCHAR(5) = '00897' 

;WITH CurrentLinks AS 
(
    SELECT 
     [tv].[ID], [tv].[NewId], [tv].[LinkDate] 
    FROM 
     @TableVals [tv] 
    WHERE 
     [tv].[NewId] = @ID 
     AND [tv].[IsUnlink] != 1 

    UNION ALL 

    SELECT 
     [tv].[ID], [tv].[NewId], [tv].[LinkDate] 
    FROM 
     @TableVals [tv] 
    INNER JOIN 
     CurrentLinks [cl] ON [tv].[NewId] = [cl].[ID] 
         AND [tv].[IsUnlink] != 1 
) 
SELECT 
    [cl].[ID] 
FROM 
    CurrentLinks cl 
WHERE 
    [cl].[id] != @ID 
    AND NOT EXISTS (SELECT 1 
        FROM @TableVals tv 
        WHERE (tv.ID = cl.ID OR tv.NewId = cl.ID) 
         AND tv.LinkDate > cl.LinkDate) 
ORDER BY 
    [cl].[LinkDate] DESC; 

當ID設置爲00903我希望0090000902要返回,當ID 00897在傳遞我希望00899008950089300891

預先感謝任何幫助或方向

+0

你想要的最終輸出是什麼? – techspider

+0

很難理解你要存檔的內容......爲什麼不能簡單地'SELECT * FROM @TableVals WHERE [NewId] ='00897''你爲什麼不要'00903'當ID是' 00897'? – techspider

+0

我也不確定這裏發生了什麼,但我有一個評論。您可以清空鏈接字段並將該值移至歸檔字段(UsedToBeLinkedTo),而不是嘗試合併IsUnlinked字段。我只是建議將此作爲層次結構的標準cte文件。 –

回答

1

我相信你的代碼是好的,但你的預期結果的期望,是因爲你的數據集的錯誤。

這個紀錄

('00903', '00897', '01 Jan 2012 11:01:57', 0), 

鏈接0090300897然後00903鏈接00900, 00901, and 00902所以你潔具適當地得到這些作爲結果,當你使用遞歸.....

+0

這就是我在想什麼,但我想也許我很困惑... –

+0

是啊我只是不得不盯着它,玩查詢幾分鐘的信息超載必須篩選....... – Matt

+0

嗯,我只是把你的不存在進入cte,並沒有得到你想要的結果,但是,我仍然有點困惑,因爲你沒有指定如何限制鏈接日期......你可以發佈您的新代碼和解釋 – Matt

0

可能是這樣的工作?

SELECT * 
FROM @TableVals tv1 
WHERE [NewId] = @ID 
     AND tv1.IsUnlink <> 1 
     AND NOT EXISTS (SELECT 1 
         FROM @TableVals tv2 
         WHERE tv2.[NewId] = tv1.[ID] 
           AND tv2.IsUnlink = 1) 
+0

不,因爲如果解除鏈接「00903」的記錄不存在,則不會返回ID「00900」和「00902」。它可能需要模式更改。使其更容易處理。 – user3047489

+0

他們不會是什麼?如果NewId ='00903'它會返回它們..你是說沒有記錄在表格中嗎? – JamieD77

+0

這適用於當前數據集。但是,當我刪除記錄'WHERE IsUnlink = 1' - 即使'00903'仍然被鏈接 - 我仍然只有四個記錄返回。在這裏,刪除了取消鏈接記錄,我希望看到所有六個返回。我不認爲這很容易做到。 – user3047489