使用子查询更新语句

Posted

技术标签:

【中文标题】使用子查询更新语句【英文标题】:Update Statement with subquery 【发布时间】:2013-10-08 03:55:39 【问题描述】:

带有子查询的 MS Access 更新语句

我有 Order 表和 OrderDetails 表。 OrderDetails 表具有带有数量和小计的订单行项目。我想运行一个查询,用对应的订单小计的总和值更新订单表中的“折扣前总金额”。

我现在的查询如下。我无法在 Access 中运行它。它告诉我“您编写的子查询可以返回多个字段,而无需在主查询 FROM 子句中使用 EXISTS 保留字。修改子查询的 SELECT 语句以仅请求一个字段。”

UPDATE [Order] INNER JOIN OrderDetails ON Order.ID = OrderDetails.[Order ID]
SET [Order].[Total Amount Before Discount] = 
    (SELECT Order.ID, Sum(OrderDetails.[Subtotal After Discount]) AS [SumOfSubtotal After Discount]
     FROM [Order] INNER JOIN OrderDetails ON Order.ID = OrderDetails.[Order ID]
     GROUP BY Order.ID)
     WHERE (((Order.ID)=[OrderDetails].[Order ID]));

【问题讨论】:

【参考方案1】:

您可以在UPDATE 查询中使用DSum Function。

UPDATE [Order] AS o
SET o.[Total Amount Before Discount] = 
    DSum
        (
            "[Subtotal After Discount]",
            "OrderDetails",
            "[Order ID]=" & o.ID
        );

注意如果[Order ID] 的数据类型是文本而不是数字,请在DSum 表达式中提供的值周围添加引号...

            "[Order ID]='" & o.ID & "'"

【讨论】:

@HansUp,我很好奇你知道 DSum 函数是否比使用子查询更快? 在这种情况下,我对此表示怀疑。您可能会经常听到DSum 较慢的说法。这里也不应该是这样。使用OrderDetails.[Order ID] 上的索引,无论哪种方式都应该相当快。【参考方案2】:

我认为您不需要加入。以下怎么样:

UPDATE [Order] 
SET [Order].[Total Amount Before Discount] = 
    (
      SELECT Sum(OrderDetails.[Subtotal After Discount])
      FROM OrderDetails 
      WHERE [Order].ID = OrderDetails.[Order ID]
    )

上述查询将更新 Order 表中每条记录的 Total Amount Before Discount。如果您只想更新某个 Order Id,请使用以下命令:

UPDATE [Order] 
SET [Order].[Total Amount Before Discount] = 
    (
      SELECT Sum(OrderDetails.[Subtotal After Discount])
      FROM OrderDetails 
      WHERE [Order].ID = OrderDetails.[Order ID]
    )
WHERE [Order].ID = 786

【讨论】:

【参考方案3】:

几个观察,UPDATE 必须重写: 重写您的查询,我们得到 - 如果您只更新一条记录,您不需要关心 GROUP BY:

UPDATE [Order]
SET [Order].[Total Amount Before Discount] = 
(Sum(OrderDetails.[Subtotal After Discount])
FROM [Order] INNER JOIN OrderDetails ON Order.ID = OrderDetails.[Order ID]
WHERE (([Order].ID)=[OrderDetails].[Order ID]);

首先,您不能更新 JOIN/INNER JOIN..

其次,您不能按照编写语句的方式更新多于一列,它必须类似于:

UPDATE [order]
SET    col1 = somevalue,
       col2 = anothervalue
WHERE  (([order].id) = [orderdetails].[Order ID]);  

希望这是有道理的。

【讨论】:

-1 你说if you are updating only one record, you don't care about the GROUP BY。然后它下面的 SQL 不会将查询限制为 一个 记录。更不用说,声明是无效的。您缺少 ) 并且 Order 是保留字,需要放在括号中。 ORDER 是保留字。但是,Access 和 SQL 将允许当您使用方括号 [ORDER] 对 Access 中的表名有效。 你是对的,但是你错过了几次出现的括号

以上是关于使用子查询更新语句的主要内容,如果未能解决你的问题,请参考以下文章

EXISTS和 NOT EXISTS 子查询 (高级查询 二)

CodeIgniter 活动记录在子查询中的位置

mysql 子句子查询连接查询

MYSQL查询语句问题 查询当月和上一月的查询语句怎么写?

请教怎么写跨库查询的SQL语句

SQL语句 怎么写?