基于两个不同的ID对表进行批量更新

时间:2014-08-14 18:59:40

标签: sql sql-server

我正在尝试在我的桌子tbl

上进行批量更新

当我执行select语句时,表格如何显示

SELECT * FROM tbl

它返回:

enter image description here

我想要完成的是进行单一更新,其中UID不同但CID相同。如果此条件为true,则更新第二个UID并使用第一个UID进行设置,并使用相同的UID设置更新UID的OLDUID。

所以输出将是这样的:

enter image description here

我在这里要完成的是如果我做一个选择陈述:

SELECT * FROM tbl where UID = 1

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

有什么建议吗?

注意* 这只是一个示例表。原始表包含数千行。还有时候我会有3或4个不同的UID但是有一个CID。这个概念仍然是一样的。使用第一个UID更新这两行,并将OLDUID与已更新的那些一起设置。

更新

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

以下是一个例子:

enter image description here

这是输出:

enter image description here

在这种情况下,它应该忽略并且什么也不做。 UID = OLDUID的所有行都是相同的类型。

2 个答案:

答案 0 :(得分:2)

您可以使用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

答案 1 :(得分:1)

这有用吗?

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上返回相同的结果