3点SQL更新查询

Posted

技术标签:

【中文标题】3点SQL更新查询【英文标题】:3 point SQL update query 【发布时间】:2012-06-19 03:49:32 【问题描述】:

我有一些怪物更新查询,如果不执行服务器端循环或其他任何操作,我无法完全适应一个查询。

我想用其他两个表中的值更新一个主帐户表。主账户有 4 列,accountID、areaID、stockID 和 amount。前三列是主键。

我要更新详细信息的两张表几乎相同,一张是传入订单,一张是传出订单。它们都包含列 orderID、stockID 和 amount。主键是 orderID 和 stockID。

还有另一个表 orders,其中包含需要引用以更新主帐户表的订单的 areaID 和 accountID。到目前为止,我可以获得一个 select 函数来获取我想要的详细信息,我只是不知道如何将它转移到更新语句。

SELECT a.*,o.orderID, SUM(io.amount) as in,SUM(oo.amount) as out
FROM account_stock AS a 
  INNER JOIN orders AS o ON o.accountID = a.accountID AND o.areaID = a.areaID 
  LEFT JOIN incoming_orders AS io ON io.stockID = a.stockID AND io.orderID = o.orderID 
  LEFT JOIN outgoing_orders AS oo ON oo.stockID = a.stockID AND oo.orderID = o.orderID
GROUP BY a.stockID,a.accountID,a.areaID

如果可以运行一个单独的更新查询,用传入和传出库存的总和更新 account_stock 文件,我就完全迷失了。

任何关于表结构更改等的建议都将受到欢迎,因为我知道我的 SQL 不是太传统。

【问题讨论】:

【参考方案1】:

您可能应该在主表中创建两列,其中包含您在 select 语句中称为“in”和“out”的内容。然而,“In”是一个保留字,所以不要使用它。我没有在示例中重命名它,所以它对你更有意义。我已经重写了语句以使其成为更新而不是选择。

update
    account_stock a,
    INNER JOIN orders AS o 
        ON o.accountID = a.accountID 
        AND o.areaID = a.areaID
    LEFT JOIN incoming_orders AS io 
        ON io.stockID = a.stockID 
        AND io.orderID = o.orderID
    LEFT JOIN outgoing_orders AS oo 
        ON oo.stockID = a.stockID 
        AND oo.orderID = o.orderID
set
    a.in=sum(io.amount),
    a.oo=sum(oo.amount)

如 cmets 中所述,这将导致 mysql 翻转饼干,因为它不喜欢 set fieldname=aggFunc() 区域中的聚合函数。

以下代码应该可以正常工作:

update
    account_stock f
set
    a.amount=(
    SELECT 
        SUM(io.amount)-SUM(oo.amount)
    FROM 
        account_stock AS a
        INNER JOIN orders AS o 
            ON o.accountID = a.accountID 
            AND o.areaID = a.areaID
        LEFT JOIN incoming_orders AS io 
            ON io.stockID = a.stockID 
            AND io.orderID = o.orderID
        LEFT JOIN outgoing_orders AS oo 
            ON oo.stockID = a.stockID 
            AND oo.orderID = o.orderID
    where
        f.stockid=a.stockid
        and f.accountid=a.accountid
        and f.areaid=a.areaid
    )

【讨论】:

这确实让我走上了正确的道路。有没有办法在最后说,a.amount = a.amount + sum(io.amount) - sum(oo.amount)? 对不起,一定是误解了这个问题。是的,您当然可以这样做,但除非您从表中删除记录,否则您可能不需要指定 a.amount=a.amount+ 等... a.amount=sum(io.amount)-sum( oo.amount) 应该可以解决问题。基本上,您将根据整个表生成一个新快照,因此您可能不需要保留最后一个值。 好吧,我明白你的意思。查询结构完美运行,我可以看到应该如何调整表结构以提高效率。 确认!我在查询中使用 SUM 时遇到问题...毫无疑问,因为我使用的是 MySQL(INNODB 结构)。 如果我取出总和值,它仍然应该更新所有匹配的行,从而给我正确的总和?因此,如果我说 a.amount = a.amount + io.amount - oo.amount 它应该给出总和,因为它会在与 stockID、areaID 和 accountID 匹配的每一行上运行??

以上是关于3点SQL更新查询的主要内容,如果未能解决你的问题,请参考以下文章

sql更新怎么根据条件查询到了更新没有匹配到的数据不更新

mysql查看一条sql更新了多少数据

MySQL45讲-2-一条SQL更新语句是如何执行的?

SQL 更新查询

使用连接的 SQL 更新查询

使用连接的 SQL 更新查询