TSQL递归CTE - 获取某个点的子记录ID

时间:2016-08-09 19:37:36

标签: sql sql-server sql-server-2008 tsql ssms

我有以下记录集,我正在尝试从父ID中获取链接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时我希望00899,{ {1}},0089500893

提前感谢任何帮助或指示

2 个答案:

答案 0 :(得分:1)

我相信您的代码很好,但由于您的数据集,您对预期结果的期望是错误的。

此记录

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

00903链接到00897,然后将00903链接到00900, 00901, and 00902,这样您就可以在使用递归时正确地获取结果.....

答案 1 :(得分: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 )