作为SQL查询分配的一部分,我必须满足以下条件:
“显示最近6个月内已购买任何商品的所有客户。显示>客户名称,会员卡号,订单日期和订单总值。>确保在查询结果中将其正确命名为Total_Order_Value。”
为此,我想出了一个被标记为错误的脚本。我认为我已经达到问题标准,对此反馈感到困惑。 在下面找到脚本和反馈:
脚本
SELECT Aorder.*, Acustomer.*, AorderDetails.quantity, (AorderDetails.quantity *AmenuItem.itemCost) AS Total_Order_Value
FROM Aorder, Acustomer, AmenuItem, AorderDetails
WHERE orderDateTime < Now() AND orderDateTime > DATE_ADD(Now(), INTERVAL -6 MONTH)
AND Acustomer.customerID = Aorder.customerID
AND Aorder.orderID = AorderDetails.orderID
AND AorderDetails.itemID = AmenuItem.itemID
AND Aorder.paymentType IN ('Cash' , 'Card');
反馈
“此刻,这将使一个订单中购买的每个商品的成本*数量相乘。您需要每个订单的总价值。即,目前我会看到我在一个订单中购买的每个商品的价值,想要查看整个订单的总数。您需要添加一个汇总和一个按“
我将很高兴为您提供帮助,帮助我了解问题所在以及如何正确构造此结构以满足要求。 预先谢谢你。
答案 0 :(得分:0)
从本质上讲,您是在订单项级别报告结果,而不是原始问题所问的客户和订单级别。您当前的结果集可能会为每个对应的项目重复客户和订单详细信息,因为它们之间的一对多关系可能很长。
要解决此问题,只需将您的SQL语句重构为一个汇总查询,即可对客户和订单商品进行分组,并对每个订单商品的值求和,以获取整个订单的总额。此外,请注意SQL中的最佳做法:
EXPLICIT JOIN:如注释中所述,请不要在FROM
子句中使用逗号匹配的旧联接样式。这称为隐式联接。 ANSI-92中引入的当前标准强调使用WHERE
和JOIN
子句的显式连接。尽管这不会改变efficiency or output,但确实有助于提高可读性和可维护性。
SELECT条款:尝试避免选择带有ON
(开放式结果集输出)的表中的所有字段。您的问题专门要求某些字段:客户名称,会员卡号,订单日期和订单总价值。因此,请相应地选择它们。
表别名:对于较长的表名和共享相同前缀,词干或后缀的表(如 A 表),请使用表缩写来正确地缩写和定义标识符。同样,这种做法不应更改输出,但有助于提高可读性和可维护性。
请参见下面的有效SQL语句(将字段名称调整为实际值)。
Aorder.*, Acustomer.*
注意:不要像大多数MySQL用户一样犯错误,即排除了ANSI-SQL要求的聚合查询的SELECT c.customer_name,
c.loyalty_card_number,
CAST(o.orderDateTime AS DATE) AS Order_Date,
SUM(d.quantity * m.itemCost) AS Total_Order_Value
FROM Aorder o
INNER JOIN Acustomer c ON c.customerID = o.customerID
INNER JOIN AorderDetails d ON o.orderID = d.orderID
INNER JOIN AmenuItem m ON d.itemID = m.itemID
WHERE o.orderDateTime < Now()
AND o.orderDateTime > DATE_ADD(Now(), INTERVAL -6 MONTH)
AND o.paymentType IN ('Cash' , 'Card')
GROUP BY c.customer_name,
c.loyalty_card_number,
CAST(o.orderDateTime AS DATE)
子句中的非聚合列。星号GROUP BY
绝对不能在聚合查询中使用。不幸的是,MySQL禁用了ONLY FULL GROUP BY
模式,允许使用此功能,并且可能返回不可靠的结果。