在单个SQL查询中更新具有不同值的多个行

时间:2012-07-19 15:12:59

标签: sql sqlite rows

我有一个SQLite数据库,其中包含表格myTable和列idposXposY。行数不断变化(可能会增加或减少)。如果我知道每行id的值和行数,我是否可以执行单个SQL查询来更新具有不同值的所有posXposY字段,具体取决于id?

例如:

---------------------
myTable:

id   posX    posY

1      35     565
3      89     224
6      11     456
14     87     475
---------------------

SQL查询伪代码:

UPDATE myTable SET posX[id] = @arrayX[id], posY[id] = @arrayY[id] "

@arrayX@arrayY是存储posXposY字段的新值的数组。

例如,如果arrayXarrayY包含以下值:

arrayX = { 20, 30, 40, 50 }
arrayY = { 100, 200, 300, 400 }

...然后查询后的数据库应如下所示:

---------------------
myTable:

id   posX    posY

1      20     100
3      30     200
6      40     300
14     50     400
---------------------

这可能吗?我现在正在为每个查询更新一行,但随着行数的增加,它将需要数百个查询。顺便说一下,我正在Air中做这一切。

7 个答案:

答案 0 :(得分:22)

有两种方法可以有效地完成

首先 -
如果可能,您可以对临时表执行某种批量插入。这在某种程度上取决于您的RDBMS /主机语言,但在最坏的情况下,这可以通过简单的动态SQL(使用VALUES()子句),然后是标准的从另一个表更新来实现。大多数系统都提供批量加载的实用程序,但

第二 -
这也有点依赖于RDBMS,您可以构造一个动态更新语句。在这种情况下,CTE内部的VALUES(...)子句是在运行中创建的:

WITH Tmp(id, px, py) AS (VALUES(id1, newsPosX1, newPosY1), 
                               (id2, newsPosX2, newPosY2),
                               ......................... ,
                               (idN, newsPosXN, newPosYN))

UPDATE TableToUpdate SET posX = (SELECT px
                                 FROM Tmp
                                 WHERE TableToUpdate.id = Tmp.id),
                         posY = (SELECT py
                                 FROM Tmp
                                 WHERE TableToUpdate.id = Tmp.id)


WHERE id IN (SELECT id
             FROM Tmp)

(根据文档,这个应该是有效的SQLite语法,但我不能让它在小提琴中工作)

答案 1 :(得分:15)

是的,你可以这样做,但我怀疑它会提高性能,除非你的查询有很大的延迟。

你可以这样做:

 UPDATE table SET posX=CASE
      WHEN id=id[1] THEN posX[1]
      WHEN id=id[2] THEN posX[2]
      ...
      ELSE posX END, posY = CASE ... END
 WHERE id IN (id[1], id[2], id[3]...);

总费用或多或少由:NUM_QUERIES *(COST_QUERY_SETUP + COST_QUERY_PERFORMANCE)。通过这种方式,您可以在NUM_QUERIES上点击一下,但COST_QUERY_PERFORMANCE会大幅提升。如果COST_QUERY_SETUP真的很大(例如,你正在调用一些真正慢的网络服务),那么,是的,你可能仍然最终处于最佳状态。

否则,我会尝试对id进行索引或修改体系结构。

在MySQL中我认为你可以通过多次INSERT ON DUPLICATE KEY UPDATE更容易地做到这一点(但我不确定,从未尝试过)。

答案 2 :(得分:5)

这样的事可能适合你:

"UPDATE myTable SET ... ;
 UPDATE myTable SET ... ;
 UPDATE myTable SET ... ;
 UPDATE myTable SET ... ;"

如果任何posX或posY值相同,则可以将它们组合成一个查询

UPDATE myTable SET posX='39' WHERE id IN('2','3','40');

答案 3 :(得分:0)

我实际上无法使@ Clockwork-Muse工作。但是我可以使这种变化起作用:

WITH Tmp AS (SELECT * FROM (VALUES (id1, newsPosX1, newPosY1), 
                                   (id2, newsPosX2, newPosY2),
                                   ......................... ,
                                   (idN, newsPosXN, newPosYN)) d(id, px, py))

UPDATE t

SET posX = (SELECT px FROM Tmp WHERE t.id = Tmp.id),
    posY = (SELECT py FROM Tmp WHERE t.id = Tmp.id)

FROM TableToUpdate t

我希望这对您也有用!

答案 4 :(得分:0)

使用逗号“,”

eg: 
UPDATE my_table SET rowOneValue = rowOneValue + 1, rowTwoValue  = rowTwoValue + ( (rowTwoValue / (rowTwoValue) ) + ?) * (v + 1) WHERE value = ?

答案 5 :(得分:0)

要更新具有 column1 不同值的表,给定 column2 上的值,可以对 SQLite 执行以下操作:

"UPDATE table SET column1=CASE WHEN column2<>'something' THEN 'val1' ELSE 'val2' END"

答案 6 :(得分:-10)

尝试使用“更新数位板集(行='值',其中id = 0001'),(行='value2',其中id = 0002'),...