复杂的MySql更新加入查询

时间:2014-06-12 19:42:54

标签: mysql join

有一个我面临的问题的例子。数据库表与平常略有不同,但需要以这种方式设置。

项目:id,order_id,其他字段

Items_Drinks:id,饮料,其他字段

订单:id,其他字段

Orders_Drinks:id,drink,other fields

我需要有一个更新查询,它将使用与Orders_Drinks id字段具有相同order_id的Items_Drinks饮料字段的总和来更新Orders_Drinks表。

Items: 1   1   ...
Items: 2   1   ...
Items_Drinks: 1   4   ...
Items_Drinks: 2   5   ...

Orders: 1   ...
Orders_Drinks: 1   9   ...

Orders_Drinks目前是正确的,但如果我要更新id为1到5的Items_Drinks,我需要一个更新命令来将ID为1的Orders_Drinks等于10。

最好是命令会更新Orders_Drinks的每条记录。

我知道我的数据库不典型,但我的应用程序需要它。这是因为所有条目都不需要Drinks表。 Drinks表中有超过5000个字段,因此如果每个记录都有这些细节,那么数据库就会变得越来越慢,没有任何理由。请不要告诉我重组数据库,这是必要的。

我目前在我的C#程序中使用for循环来做我需要的东西,但是拥有1个命令可以节省大量的时间!

这是我最好的尝试,但它会出现错误的"无效的群组功能"。

update Orders_Drinks join Items on Items.order_id=Orders_Drinks.id join Items_Drinks on Items_Drinks.id=Items.id set Orders_Drinks.drinks=sum(Item_Drinks.drinks);

3 个答案:

答案 0 :(得分:1)

我认为这就是你想要的。

编辑:

UPDATE `Order_Drinks` a 
SET a.`drinks` = (SELECT SUM(b.`drinks`) FROM `Items_Drinks` b INNER JOIN `Items` c ON (b.`id` = c.`id`) WHERE a.`id` = c.`order_id`)

对于行ID为1,Order_Drinks表应该总共给出9个。

这假设Orders.id == Orders_Drinks.id和Items.id == Items_Drinks.id。

答案 1 :(得分:1)

您需要进行聚合。您可以在join声明的update部分执行此操作:

update Orders_Drinks od join
       (select i.order_id, sum(id.drinks) as sumdrinks
        from Items i join
             Items_Drinks id
             on id.id = i.id
       ) iid
       on iid.order_id = od.id
    set od.drinks = iid.sumdrinks;

答案 2 :(得分:0)

这样的内容将返回id表中的orders_drinks以及drinks摘要字段的当前值,以及从相关{{1}派生的新摘要值表格。

(如果没有外键列的名称,我假设外键列名称的格式为:" referenced_table_id")

items_drinks

一旦我们编写了SELECT查询以获得我们想要的结果,我们就可以将其更改为UPDATE语句。只需使用SELECT od.id , od.drinks AS old_drinks , IFNULL(td.tot_drinks,0) AS new_drinks FROM orders_drinks od LEFT JOIN ( SELECT di.orders_drinks_id , SUM(di.drinks) AS tot_drinks FROM items_drinks di GROUP BY di.orders_drinks_id ) td ON td.orders_drinks_id = od.id 关键字替换SELECT ... FROM,然后添加UPDATE子句,即可将值分配/替换为SET列。

e.g。

drinks

(注意:IFNULL函数是可选的。只要找到UPDATE orders_drinks od LEFT JOIN ( SELECT di.orders_drinks_id , SUM(di.drinks) AS tot_drinks FROM items_drinks di GROUP BY di.orders_drinks_id ) td ON td.orders_drinks_id = od.id SET od.drinks = IFNULL(td.tot_drinks,0) 中没有匹配的行,或者只要总数为NULL,我就用它来代替零值。)

这将更新items_drinks表中的所有行(需要更新)。如果您只想更新orders_drinks中的特定行而不是所有行,则可以添加WHERE子句(在SET子句之后):

orders_drinks

再次,为了达到这个目的,首先得到一个SELECT语句,用于返回要分配给列的新值,以及要更新的表的键。一旦它工作,将其转换为UPDATE语句,将返回新值的表达式向下移动到SET子句。