【问题标题】:Update row based on multiple relations基于多个关系更新行
【发布时间】:2013-09-04 13:24:42
【问题描述】:

我有三张桌子:

  • 套件(kit_id、kit_weight)
  • Kit_Components(kit_id、数量、component_id)
  • 组件(component_id、重量)

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

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


编辑:为了进一步澄清,我可以对权重 * 数量求和,但这不涉及为 NULL 的组件行,因为 NULL 在 SUM 中充当 0(我已经对此进行了测试)

例如Kit1 有 1xComponentA,权重为 14,2xComponentB,权重为 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

这将为 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。”

【问题讨论】:

  • 您可能需要一个 UPDATE 语句。以及聚合子查询上的 SUM()。甚至可能是乘法!!!
  • 为什么需要group by子句,没有它你得到你想要的
  • @ilan-berci 有什么不同吗?

标签: mysql


【解决方案1】:

根据您的编辑,您的问题似乎是让以下查询返回 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>) 计算字段中非空值的数量。因此,计数本质上是说“所有值都不为空”,或者等效地,“没有值是空的”。

【讨论】:

  • 感谢您的回答,是的,这就是我一直在寻找的,但是我找到了一个替代方案,我也已经发布了。
【解决方案2】:

环顾四周后,我意识到问题在于 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

如果其中任何组件的权重为空,则这会将套件表的权重更新为空,如果所有组件的值都有效,则将其总权重更新为空。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 2022-01-22
    • 2017-01-30
    相关资源
    最近更新 更多