2015-03-06 3 views
0

Пожалуйста, укажите, как использовать cross join для приведенной ниже таблицыКреста присоединиться на одной таблице

ID level parentid grandparentid 
1 1  205  280 
2 1  206  281 
3 2 null  280 
4 2 null  280 
5 2 null  281 

Теперь я хочу быть, как показано ниже в обновлении собственной таблицы

ID level parentid grandparentid 
1 1  205  280 
2 1  206  281 
3 2  205  280 
4 2  205  280 
5 2  206  281 

Я хочу, чтобы заполнить родитель id, если grandparentid соответствует уровню 1 и уровню 2 , используя инструкцию update для обновления нулевых значений.

ответ

3

Вы можете получить результаты в select. Я думаю, что самый простой способ это коррелированные подзапросы (или outer apply):

select t.id, t.level, 
     coalesce(t.parentid, 
       (select top 1 t2.parentid 
       from table t2 
       where t2.grandparentid = t.grandparentid and 
         t2.parentid is not null 
       ) 
       ) as parentid, 
     t.grandparentid 
from table t ; 

Вы можете включить это в инструкцию обновления, если вы действительно хотите изменить данные.

update t 
    set parentid = (select top 1 t2.parentid 
        from table t2 
        where t2.grandparentid = t.grandparentid and 
          t2.parentid is not null 
        ) 
    from table t 
    where parentid is null; 
0
UPDATE t2 SET parentid=t1.parentid 
--SELECT * 
FROM Table t1 
INNER JOIN Table t2 ON t1.grandparentid=t2.grandparentid 
    AND t2.parentid IS NULL 
    AND t1.Level=t2.Level-1 
0

Вы можете сделать это с помощью JOIN также:

DECLARE @t TABLE 
    (
     ID INT , 
     Level INT , 
     ParentID INT , 
     GrandparentID INT 
    ) 

INSERT INTO @t 
VALUES (1, 1, 205, 280), 
     (2, 1, 206, 281), 
     (3, 2, NULL, 280), 
     (4, 2, NULL, 280), 
     (5, 2, NULL, 281) 


UPDATE t1 
SET  ParentID = t2.ParentID 
FROM @t t1 
     LEFT JOIN @t t2 ON t1.GrandparentID = t2.GrandparentID 
WHERE t1.ParentID IS NULL 

SELECT * FROM @t 

Выход:

ID Level ParentID GrandparentID 
1 1  205   280 
2 1  206   281 
3 2  205   280 
4 2  205   280 
5 2  206   281 
0

Прежде всего, прародитель может иметь много детей или ParentID в этом случае , поэтому не является хорошим предположением, что только потому, что отношения между родителем и ребенком существуют на уровне 1, он также будет существовать на уровне 2.

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

Если вы намерены запустить обновление, вы должны по крайней мере обеспечить что есть один и только один ParentID для каждого grandparentId назначенного на уровне 1 перед обновлением строки на уровне 2.

Вот пример:

DECLARE @Table TABLE 
(
    ID INT PRIMARY KEY IDENTITY 
    ,Level INT 
    ,ParentId INT 
    ,GrandparentId INT 
); 

INSERT INTO @Table 
(
    Level 
    ,ParentId 
    ,GrandparentId 
) 
VALUES 
    (1,  205,  280) 
    ,(1, 206,  281) 
    ,(1, 207,  282) 
    ,(1, 208,  282) 
    ,(2, null, 280) 
    ,(2, null, 280) 
    ,(2, null, 281) 
    ,(2, null, 282); 

SELECT * FROM @Table; 

UPDATE T SET ParentId = T2.TheOneAndOnlyParentId 
FROM 
    @Table T 
JOIN 
(
    SELECT 
     GrandparentId 
     ,MAX(ParentID) AS TheOneAndOnlyParentId 
    FROM 
     @Table 
    WHERE 
     ParentId IS NOT NULL 
     AND Level = 1 
    GROUP BY 
     GrandparentId 
    HAVING 
     MIN(ParentID) = MAX(ParentID) 
) T2 
    ON T.GrandparentId = T2.GrandparentId 
WHERE 
    T.Level = 2; 

SELECT * FROM @Table; 

Обратите внимание, как один уровень-два строка не была обновлена , Это связано с тем, что отношения уровня один были неясны.