在单个表上交叉连接

时间:2015-03-06 14:26:32

标签: sql sql-server

请建议如何在下表中使用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

如果grandparentid在1级和2级匹配,我想填写父ID 使用update语句更新空值。

4 个答案:

答案 0 :(得分: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;

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

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

答案 3 :(得分:0)

首先,祖父母可能有很多孩子,或者在这种情况下是父母,所以不是一个好的假设,仅仅因为1级中存在父子关系,它也会存在于水平2。

所以,我建议深入研究数据,看看是否有任何方法可以找到第2级的真实关系。

如果您打算运行更新,那么在更新第2级的行之前,至少应该确保在级别1上为每个grandparentId分配一个且只有一个parentId。

以下是一个例子:

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;

注意一个二级行没有更新。这是因为一级关系不明确。