我有一个大约 106k 行的表,其中大约 11k 行交换了 2 列中的值。我想运行一个查询来修复它,但我认为我不能这样做:
UPDATE `game`
SET `homescore`=`awayscore`, `awayscore`=`homescore`
WHERE (`awayscore`>`homescore` AND `winner`=`hometeam`) OR (`awayscore`<`homescore` AND `winner`=`awayteam`);
Run Code Online (Sandbox Code Playgroud)
或者我可以吗?我担心这两个分数最终会得到相同的值。
另外,请验证我的查询是否符合我的意图:
我需要在记录的获胜者(这是正确的)与记录的分数不匹配的行上交换主客场得分(他们被现已修复的编码错误意外交换)说谁是获胜者(得分更高的球队) )。
在任何体面的 RDBMS(例如 Postgres、SQL-Server、Oracle、DB2)中,简单的方法都可以正常工作并交换两列的值:
UPDATE game
SET homescore = awayscore,
awayscore = homescore
WHERE (awayscore > homescore AND winner = hometeam)
OR (awayscore < homescore AND winner = awayteam) ;
Run Code Online (Sandbox Code Playgroud)
在 MySQL 中,它不会按预期工作!您必须使用某种技巧,例如:
UPDATE game
SET homescore = (@tmp := homescore),
homescore = awayscore,
awayscore = @tmp
WHERE (awayscore > homescore AND winner = hometeam)
OR (awayscore < homescore AND winner = awayteam) ;
Run Code Online (Sandbox Code Playgroud)
您还可以在表中再添加一两列,使用它们进行交换,然后删除它们,但效率不会很高。更好的方法是使用另一个(临时)表:
CREATE TABLE temp_swap
( pk INT NOT NULL -- whatever datatype the Primary Key of your table is
, homescore INT -- INT or FLOAT or DECIMAL
, awayscore INT -- whatever the two columns are
, PRIMARY KEY (pk)
) ;
Run Code Online (Sandbox Code Playgroud)
复制要在那里交换的值:
INSERT INTO temp_swap
(pk, homescore, awayscore)
SELECT pk, homescore, awayscore
FROM game
WHERE (awayscore > homescore AND winner = hometeam)
OR (awayscore < homescore AND winner = awayteam) ;
Run Code Online (Sandbox Code Playgroud)
然后返回,交换,进入表:
UPDATE game AS g
JOIN temp_swap AS t
ON t.pk = g.pk
SET g.homescore = t.awayscore,
g.awayscore = t.homescore ;
DROP TABLE temp_swap ;
Run Code Online (Sandbox Code Playgroud)
您的担忧是有效的,mysql 文档说
如果在表达式中访问要更新的表中的列,UPDATE 将使用该列的当前值。例如,以下语句将 col1 设置为比其当前值大 1: UPDATE t1 SET col1 = col1 + 1;
以下语句中的第二个赋值将 col2 设置为当前(更新后的) col1 值,而不是原始 col1 值。结果是 col1 和 col2 具有相同的值。此行为不同于标准 SQL。
更新 t1 SET col1 = col1 + 1, col2 = col1;
为了解决这个问题,我建议添加 2 列,比如说homescore_old
和awayscore_old
,复制homescore
并awayscore
在那里,然后你UPDATE
在右侧分配中使用新添加的列。完成后,您可以删除old
列。也可以只使用一列额外的列,但同样,文档指出,
单表 UPDATE 分配通常从左到右进行评估。
在我的理解中,“一般”与“总是”不同。
归档时间: |
|
查看次数: |
4242 次 |
最近记录: |