根据多个关系更新行

时间:2013-09-04 13:24:43

标签: mysql

我有三张桌子:

  • 套件(kit_id,kit_weight)
  • Kit_Components(kit_id,quantity,component_id)
  • 组件(component_id,weight)

对于kits表中的每个条目,可以有一个或多个Kit_Component条目。每个组件都有一个重量列,如果我们还没有称重,它可以是重量,也可以为零。我需要做的是运行SQL查询来更新Kits表的权重列,基于其所有组件的总权重乘以数量,或者如果任何权重为null,则将其值设置为null但我甚至不确定它可能,是吗?

注意:我想避免脚本,触发器或程序。我有代码在保存组件或更新套件时执行此操作,但我希望能够批量执行此操作。


编辑:为了进一步说明我可以对权重*数量进行求和但是这不会处理组件行为NULL,因为在SUM中NULL作为0(我已经测试过了)

E.g。 Kit1具有1xComponentA,权重为14,2xComponentB,权重为NULL

SELECT kit_id,SUM(component.weight * kit_component.quantity)FROM kit_component INNER JOIN组件ON kit_component.component_id = component.id GROUP BY kit_component.kit_id

对于kit1,这将返回14,但这是错误的,因为ComponentB没有重量,所以应该返回NULL。

Hugo Kornelis: “如果组中的数据(由GROUP BY组成)有一些NULL和一些 非NULL数据,忽略NULL,结果是总和 剩余数字:SUM {1,3,NULL,5} = SUM {1,3,5} = 9 如果组中的所有数据都为NULL,则也会忽略NULL 没有要汇总的行:结果是空集的总和;通过 定义这是NULL。 SUM {NULL,NULL} = SUM {} = NULL。“

2 个答案:

答案 0 :(得分:0)

根据您的修改,您的问题似乎是当进入NULL的任何值时,让以下查询返回NULL

SELECT kit_id, SUM(component.weight * kit_component.quantity)
FROM kit_component INNER JOIN
     component
     ON kit_component.component_id = component.id
GROUP BY kit_component.kit_id

您可以使用其他逻辑执行此操作:

SELECT kit_id,
       (case when count(component.weight) = count(*) and
                  count(component.quantity) = count(*)
             then SUM(component.weight * kit_component.quantity)
        end)
FROM kit_component INNER JOIN
     component
     ON kit_component.component_id = component.id
GROUP BY kit_component.kit_id

记住count(<field>)计算字段中非NULL值的数量。因此,计数基本上是说“所有值都是非空的”,或者等价地说“没有值为空”。

答案 1 :(得分:0)

在查看了一下后,我意识到问题是SUM处理具有一些NULL值的分组的方式。找到这篇文章SQL query to return NULL for SUM(expression) whenever an included value IS NULL后,我制定了一个决议,其内容如下:

UPDATE kits
        LEFT JOIN
    (SELECT 
        kit_id,
            IF(SUM(component.weight is NULL), NULL, SUM(component.weight * kit_component.quantity)) AS total_weight
    FROM
        kit_component
    INNER JOIN component ON kit_component.component_id = component.id
    GROUP BY kit_component.kit_id) AS weights ON kits.id = weights.kit_id 
SET 
    kits.weight = weights.total_weight

如果任何组件权重为null或总权重(如果所有组件都具有有效值),则会将套件表权重更新为null。