2014-10-23 6 views
2

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

Вот некоторые выборочные данные, чтобы показать, что я пытаюсь выполнить:

CREATE TABLE #temp_data 
(
item_id int, 
item_name varchar(100), 
related_item_id int, 
related_item_name varchar(100) 
) 

INSERT INTO #temp_data 
select 10, 'apple', 20 , 'orange' UNION ALL 
select 20, 'orange', 30 , 'grape' UNION ALL 
select 30, 'orange', NULL , NULL UNION ALL 
select 100, 'tomato', 200 , 'onion' UNION ALL 
select 200, 'onion', 300 , 'tomato' UNION ALL 
select 400, 'cucumber',100 , 'tomato' UNION ALL 
select 300, 'pepper', NULL , NULL UNION ALL  
select 500, 'lettuce', 400 , 'cucumber' UNION ALL 
select 1000, 'beef' , NULL, NULL UNION ALL 
select 10000, 'cheese, NULL, NULL 

Ожидаемые результаты:

group_id item_id item_name related_item_id related_item_name 
    1   10  apple  20    orange 
    1   20  orange  30    grape 
    1   30  orange  NULL   NULL 
    2   100  tomato  200    onion 
    2   200  onion  300    tomato 
    2   300  pepper  NULL   NULL 
    2   400  cucumber  100   tomato 
    2   500  lettuce  400    cucumber 
    3   1000 beef  NULL   NULL 
    4   10000 cheese  NULL   NULL 

Я пытался сделать это с помощью рекурсивных CTE, но я не имел удачи.

+2

Пожалуйста, измените свой пост, чтобы показать вашу попытку КТР, и то, что было неправильно с результатами. –

+0

Данные, приведенные выше, были всего лишь некоторыми примерными данными, чтобы проиллюстрировать пример. Я пытаюсь понять, как написать логику, чтобы показать взаимосвязь между записями с совпадением item_id/related_item_ids. Например, A = B и B = C, мне трудно написать логику, чтобы показать A = C. – bob

+0

Может ли быть группа элементов, в которой у одного из них нет 'related_item_id = NULL'? Является ли отношение всегда простым деревом или могут быть циклы в отношениях между элементами? Если одно из них верно, тогда ответ будет другим. Ключевой частью данных примера является то, что он полностью фиксирует нюансы и сложности, связанные с вашим фактическим набором данных. – mellamokb

ответ

3

Вот одно решение

;WITH T AS (
    SELECT 
     ROW_NUMBER() OVER (ORDER BY item_id) AS group_id, 
     * 
    FROM #temp_data T 
    WHERE related_item_Id IS NULL 
    UNION ALL 
    SELECT T.group_id, T1.* 
    FROM T 
     INNER JOIN #temp_data T1 
      ON T.item_id = T1.related_item_id 
) 

SELECT * FROM T ORDER BY group_id, item_id 

Выходом является

group_id    item_id  item_name  related_item_id related_item_name 
-------------------- ----------- --------------- --------------- ----------------- 
1     10   apple   20    orange 
1     20   orange   30    grape 
1     30   grape   NULL   NULL 
2     100   tomato   200    onion 
2     200   onion   300    tomato 
2     300   pepper   NULL   NULL 
2     400   cucumber  100    tomato 
2     500   lettuce   400    cucumber 
+0

SQLFiddle с решением (расширенный бит для удобочитаемости): http://sqlfiddle.com/#!6/919d8/11 – JNevill

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