更新重复值;

时间:2012-03-21 15:46:02

标签: sql sql-server

我有一个包含唯一索引的表;比如说

A B
1 1
1 2
1 3
1 4

我想要更新B列,因为如果sql尝试将第一列更新为2,那么sql会逐一更新它们,因为ex i get ::

A B
1 2
1 2
1 3
1 4

结果我会在第1行和第2行得到两个重复的值,当然还有错误信息。

我应该像那样更新表格:

A B
1 2
1 1
1 3
1 4

那么在这种情况下我应该遵循的行动方案是什么?

问候。

也许我应该更新问题: 如果我想完全改变b列怎么办?如:

A B
1 4
1 2
1 3
1 1

3 个答案:

答案 0 :(得分:3)

试试这个

UPDATE tbl
SET B = 3 - B
WHERE A = 1 AND B IN (1, 2)

或者,通常,你可以使用类似的东西:

UPDATE tbl
SET B = CASE B 
        WHEN 1 THEN 2 
        WHEN 2 THEN 1 
    END
WHERE A = 1 AND B IN (1, 2)

另一种方式:
添加列C
通过循环填充C列,使用新值
从C:更新字段B:

UPDATE tbl
SET B = C

答案 1 :(得分:0)

如果我理解的话,你有一个由两列组成的主键,并且你想要将两个第一行交换为PK。

如果您没有引用此主键的外键,只需将其中一个键更改为临时未使用的值:

A B
1 10000
1 2

然后改变第二行:

A B
1 10000
1 1

最后,改变第一个:

A B
1 2
1 1

如果您有依赖于此主键的对象,则必须将其他列的副本(例如11的其他列)复制到“临时行”,复制第二列的数据(1 2) )到第一个(1 1)并最终将“临时行”复制到第二个(1 2)

这一切都取决于你正在尝试做的事情和方式。它是一个存储过程,是一个查询...你应该显示更多的上下文。

您可以将此技术应用于无限数量的行。您还可以创建具有键等价的临时表,并从临时表更新表。因此,它将在原子操作中完成,并且不会违反PK。

create table T
(A int, B int, C char(5),
primary key (A,B))

insert into T values(1,1,'first')
insert into T values(1,2,'secon')
insert into T values(1,3,'third')

create table #KeyChanges
(A int, B int, newA int, newB int)

insert into #KeyChanges values(1,1,1,3)
insert into #KeyChanges values(1,2,1,1)
insert into #KeyChanges values(1,3,1,2)

update T set T.A = KC.newA, T.B = KC.newB
from T
left join #KeyChanges as KC on T.A = KC.A and T.B = KC.B

答案 2 :(得分:0)

解决方案是在单个语句中进行交换:

UPDATE YOUR_TABLE
SET B = (CASE B WHEN 1 THEN 2 ELSE 1 END)
WHERE A = 1 AND B IN (1, 2)

---编辑---

要一次更新多行,您可以从临时表中执行JOIN更新:

CREATE TABLE #ROWS_TO_UPDATE (
    A int,
    B int,
    NEW_B int,
    PRIMARY KEY (A, B)
);

INSERT INTO #ROWS_TO_UPDATE (A, B, NEW_B) VALUES (1, 1, 4);
INSERT INTO #ROWS_TO_UPDATE (A, B, NEW_B) VALUES (1, 2, 3);
INSERT INTO #ROWS_TO_UPDATE (A, B, NEW_B) VALUES (1, 3, 2);
INSERT INTO #ROWS_TO_UPDATE (A, B, NEW_B) VALUES (1, 4, 1);

UPDATE YOUR_TABLE
SET B = NEW_B
FROM
    YOUR_TABLE JOIN #ROWS_TO_UPDATE
        ON YOUR_TABLE.A = #ROWS_TO_UPDATE.A AND YOUR_TABLE.B = #ROWS_TO_UPDATE.B;

DROP TABLE #ROWS_TO_UPDATE;

以上代码转换以下数据......

A B
1 1
1 2
1 3
1 4

......对此:

A B
1 4
1 2
1 3
1 1