2016-08-09 3 views
1

У меня есть следующий набор записей, который я пытаюсь получить список связанных идентификаторов из заданного родительского идентификатора.TSQL Рекурсивный CTE - получить идентификатор записи до определенной точки

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) 

У меня есть этот КТР, который возвращает две неожиданных значений (00900 и 00902), так как они связаны с 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 я ожидаю 00900 и 00902 быть возвращены, и когда ID 00897 передается в Я ожидаю 00899, 00895, 00893 и 00891.

Заранее спасибо за любую помощь или направление

+0

Какой у вас конечный результат? – techspider

+0

Трудно понять, что вы пытаетесь достичь ... почему это не может быть просто 'SELECT * FROM @TableVals WHERE [NewId] = '00897'', почему вы не хотите' 00903' WHEN ID является ' 00897 '? – techspider

+0

Я также не совсем уверен, что здесь происходит, но у меня есть комментарий. Вы можете удалить поле ссылки и перенести значение в поле архива (UsedToBeLinkedTo), а не пытаться включить поле IsUnlinked. Я предлагаю это только в качестве стандартного элемента иерархии, хорошо документированного. –

ответ

1

Я считаю, что ваш код хорошо, но ваши ожидания от ожидаемого результата является неправильным из-за набор данных.

записи

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

ссылки 00903 на 00897, а затем 00903 ссылки на 00900, 00901, and 00902 так что вы Ware надлежащим образом получать те результаты, как при использовании рекурсии .....

+0

Thats, о чем я думал, но я подумал, может быть, я был в замешательстве ... –

+0

Да, мне просто нужно было смотреть на него и играть с запросом в течение нескольких минут, перегрузка информации должна была просеиваться через ....... – Matt

+0

hmmm Я просто переместил ваш не существует в 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', не была там, тогда идентификаторы' 00900' и ​​'00902' не будут возвращены. Вероятно, это требует изменения схемы. Чтобы упростить работу. – user3047489

+0

что бы они не сделали? .. если NewId = '00903', они вернут их .. вы говорите, что ни одна из записей не была бы в таблице? – JamieD77

+0

Это работает для текущего набора данных. Но когда я удаляю записи 'WHERE IsUnlink = 1' - то есть, так что' 00903' все еще связан - я все еще получаю только четыре записи. Здесь, удалив записи unlink, я ожидал увидеть все шесть возвращенных. Я не думаю, что это легко выполнимо. – user3047489

Смежные вопросы