代码之家  ›  专栏  ›  技术社区  ›  smr5

根据两个不同的ID对表进行批量更新

  •  1
  • smr5  · 技术社区  · 10 年前

    我想在我的桌子上做一次大规模更新 tbl

    这是我执行select语句时表格的样子

    SELECT * FROM tbl
    

    它返回以下内容:

    enter image description here

    我试图完成的是在UID不同但CID相同的情况下进行一次更新。如果此条件为真,则更新第二个UID并将其设置为第一个UID,并设置OLDUID,其中UID使用相同的UID更新。

    因此输出如下:

    enter image description here

    我在这里要做的是,如果我做一个select语句:

    SELECT * FROM tbl where UID = 1
    

    它应该返回两行。我曾尝试连接这两个表,然后进行更新,但每次尝试在更新之前执行select语句时,它都会返回比预期更多的行。

    有什么建议吗?

    注释* 这只是一张示例表。原始表包含数千行。此外,有时我会有3或4个不同的UID,但只有一个CID。这个概念仍然是一样的。使用第一个UID更新两行,并使用更新的UID设置OLDUID。

    更新:

    在某些情况下,两行具有相同的CID,但UID也相同。在这种情况下,我不想更新和设置OLDUID。

    下面是一个示例:

    enter image description here

    以下是输出:

    enter image description here

    在这种情况下,它应该忽略而不做任何事情。UID=OLDUID的所有行都是相同的类型。

    2 回复  |  直到 10 年前
        1
  •  2
  •   Hart CO    10 年前

    您可以使用cte和 ROW_NUMBER() 函数以及窗口 MIN() :

    with cte AS (SELECT *,ROW_NUMBER()OVER(PARTITION BY CID ORDER BY UID) RN
                          ,MIN(UID) OVER(PARTITION BY CID) Min_UID
                  FROM Table1
                  )
    UPDATE cte
    SET OLDUID = UID
       ,UID = MIN_UID
    WHERE RN > 1
    

    演示: SQL Fiddle

    更新: 若要处理UID相同且不想更新的其他情况,您只需将 WHERE 标准:

    with cte AS (SELECT *,ROW_NUMBER()OVER(PARTITION BY CID ORDER BY UID) RN
                          ,MIN(UID) OVER(PARTITION BY CID) Min_UID
                  FROM Table1
                  )
    UPDATE cte
    SET OLDUID = UID
       ,UID = MIN_UID
    WHERE RN > 1
      AND UID <> MIN_UID
    

    演示: SQL Fiddle

        2
  •  1
  •   Beth    10 年前

    这行吗?

    UPDATE
        tbl
    SET olduid = uid, uid = min_uid
    FROM
        tbl INNER JOIN
        (SELECT
            cid,
            MIN(uid) AS min_uid
        FROM
            tbl
        GROUP BY
            cid) mn ON
        tbl.cid = mn.cid AND
        tbl.uid <> min_uid
    

    fyi,在上面的SQL Fiddle上返回相同的结果