Mysql 编写多个更新查询的更有效方法

Mysql 编写多个更新查询的更有效方法,mysql,sql,database,oracle,Mysql,Sql,Database,Oracle,是否有更好/更高效/更短的方法来编写此SQL查询: UPDATE mTable SET score = 0.2537 WHERE user = 'Xthane' AND groupId = 37; UPDATE mTable SET score = 0.2349 WHERE user = 'Mike' AND groupId = 37; UPDATE mTable SET score = 0.2761 WHERE user = 'Jack' AND groupId = 37; UPDATE mT

是否有更好/更高效/更短的方法来编写此SQL查询:

UPDATE mTable SET score = 0.2537 WHERE user = 'Xthane' AND groupId = 37;
UPDATE mTable SET score = 0.2349 WHERE user = 'Mike' AND groupId = 37;
UPDATE mTable SET score = 0.2761 WHERE user = 'Jack' AND groupId = 37;
UPDATE mTable SET score = 0.2655 WHERE user = 'Isotope' AND groupId = 37;
UPDATE mTable SET score = 0.3235 WHERE user = 'Caesar' AND groupId = 37;
您可以使用语句执行这种类型的
UPDATE

UPDATE mTable
SET score 
   = CASE user
        WHEN 'Xthane' THEN 0.2537
        WHEN 'Mike' THEN 0.2349
        WHEN 'Jack' THEN 0.2761
        WHEN 'Isotope' THEN 0.2655
        WHEN 'Caesar' THEN 0.3235
        ELSE score
     END
WHERE groupId = 37
您可以使用语句执行这种类型的
UPDATE

UPDATE mTable
SET score 
   = CASE user
        WHEN 'Xthane' THEN 0.2537
        WHEN 'Mike' THEN 0.2349
        WHEN 'Jack' THEN 0.2761
        WHEN 'Isotope' THEN 0.2655
        WHEN 'Caesar' THEN 0.3235
        ELSE score
     END
WHERE groupId = 37

您可以创建一个临时表,为所有要更新的记录插入score、user和groupid,然后执行以下操作:

UPDATE
FROM mTable m
INNER JOIN tmpTable t
  ON m.groupId = t.groupId
  AND m.user = t.user
SET m.score = t.score;

您可以创建一个临时表,为所有要更新的记录插入score、user和groupid,然后执行以下操作:

UPDATE
FROM mTable m
INNER JOIN tmpTable t
  ON m.groupId = t.groupId
  AND m.user = t.user
SET m.score = t.score;

您的原始语句看起来足够短,并且很容易理解,您可以确定每个单独的UPDATE语句上是否有任何行受到影响

但是,对于大量的语句,执行每个语句时需要对数据库进行“往返”,这会产生相当大的开销。通过在单个语句执行中“批处理”更新,您可以获得更快速的执行(更短的运行时间)

所以,这取决于你想要实现什么

更好?这取决于你如何定义它。(这些语句是否应该更易于理解、更易于调试、资源消耗更少

效率更高?就减少运行时间而言,是的,有其他方法来完成这些相同的更新,但这些语句不像您的语句那么容易理解

更短?对于字符更少的SQL语句,是的,有一些方法可以实现这一点。(其他答案中显示了一些示例,但请注意,其中一些答案中的语句的效果与您的语句明显不同。)


这些替代方案的实际性能实际上将取决于行数和可用索引(例如,如果您有数十万行的groupId=37,但只更新其中的5行).

您的原始语句看起来很短,并且很容易理解,您可以确定每个单独的UPDATE语句上是否有受影响的行

但是,对于大量的语句,执行每个语句时需要“往返”数据库,这会带来相当大的开销。通过在单个语句执行中“批处理”这些更新,可以更快地执行大量更新(更短的运行时间)

所以,这取决于你想要实现什么

更好?取决于你是如何定义的。(这些语句应该更容易理解,更容易调试,资源消耗更少吗?)

效率更高?就减少运行时间而言,是的,有其他方法来完成这些相同的更新,但这些语句不像您的语句那么容易理解

更短?对于字符更少的SQL语句,是的,有一些方法可以实现这一点。(其他答案中显示了一些示例,但请注意,其中一些答案中的语句的效果与您的语句明显不同。)



这些替代方案的实际性能实际上将取决于行数和可用索引(例如,如果您有数十万行的groupId=37,但只更新其中的5行).

这可能会更新比原始行更多的行,并为groupId=37且用户与CASE表达式中列出的不匹配的行分配一个NULL作为分数。CASE表达式中确实需要一个
ELSE分数
,以保证我们不会更新那些“不匹配”的行行。或者是用户列上限制要更新的行的谓词。@spencer7593您是对的,我更新了它。我在编写查询时错过了它。thx这可能会更新比原始行更多的行,并为groupId=37且用户与C中列出的一行不匹配的行分配空值作为分数ASE表达式。在CASE表达式中确实需要一个
ELSE分数
,以保证我们不会更新那些“不匹配的”行。要么是该行,要么是用户列上限制要更新行的谓词。@spencer7593您是对的,我更新了它。我在编写查询时错过了它。Thx软件建议的一些解决方案有可能更新比原始行多得多的行,用空值覆盖现有的分数值,其中r原始语句不会这样做。用户的数量会改变吗?或者组的数量会改变吗?这个查询是动态构造的吗?或者更新是常量,只有分数会改变吗?请注意,一些建议的解决方案可能会更新比原始解决方案多得多的行,从而覆盖现有的分数va使用NULL表示lue,您的原始语句不会这样做。用户数会发生变化吗?或者组数会发生变化吗?此查询是动态构造的吗?或者更新常量和分数会发生变化吗?我会在用户上添加where条件,这样您就不会更新1000000行了(大多数具有与当前相同的值)当只需要更新5条记录时。@HLGEM这取决于数据-可能groupId 37只有5个用户。这是真的-您确实需要知道您的数据,但我希望OP意识到他可能会更新比预期更多的记录。这非常有效。它更新了groupId=37的所有行,但没有更新的行除外nged保持不变。大约有16行,所以这不是问题。谢谢:)@HLGEM:在Oracle中,更新数十万不需要更新的行是昂贵的(在并发性、回滚和重做方面)。也许他确实希望为每一行启动更新时的
触发器,以触发所有“未更改”的行但是为什么不到此为止,为什么不将groupId上的谓词移动到case表达式中,只更新表中的所有行呢