有没有更好的方法来编写这个SQL语句?

时间:2010-02-20 19:02:37

标签: sql group-by

我在SQL查询中获取并计算一些基本的订单信息。我有它应该工作,但已阅读有关GROUP BY SQL子句。我想知道以下SQL语句是否会受益于GROUP BY以及它是否会更有效地使用它?谢谢!

SELECT orders.billerID, 
orders.invoiceDate, 
orders.txnID, 
orders.bName, 
orders.bStreet1, 
orders.bStreet2, 
orders.bCity, 
orders.bState, 
orders.bZip, 
orders.bCountry, 
orders.sName, 
orders.sStreet1, 
orders.sStreet2, 
orders.sCity, 
orders.sState, 
orders.sZip, 
orders.sCountry, 
orders.paymentType, 
orders.invoiceNotes, 
orders.pFee, 
orders.shipping, 
orders.tax, 
orders.reasonCode, 
orders.txnType, 
orders.customerID, 
customers.firstName AS firstName, 
customers.lastName AS lastName, 
customers.businessName AS businessName, 
orderStatus.statusName AS orderStatus, 
(IFNULL(SUM((orderItems.itemPrice * orderItems.itemQuantity)), 0.00) + orders.shipping + orders.tax) AS orderTotal, 
((IFNULL(SUM((orderItems.itemPrice * orderItems.itemQuantity)), 0.00) + orders.shipping + orders.tax) - (SELECT IFNULL(SUM(payments.amount), 0.00) FROM payments WHERE payments.orderID = orders.id)) AS orderBalance 
FROM orders 
LEFT JOIN customers ON orders.customerID = customers.id 
LEFT JOIN orderStatus ON orders.orderStatus = orderStatus.id
LEFT JOIN orderItems ON orderItems.orderID = orders.id 
LEFT JOIN payments ON payments.orderID = orders.id

1 个答案:

答案 0 :(得分:2)

GROUP BY可能会允许SQL引擎更好地优化您的查询,但由于大量的分组参数会使其更难阅读。

SQL Team建议的另一个选项是考虑使用Sub查询。这通常可以使GROUP BY语句更加简单,并使整个查询更容易阅读。

使用子查询:

SELECT orders.billerID, 
    orders.invoiceDate, 
    orders.txnID, 
    orders.bName, 
    orders.bStreet1, 
    orders.bStreet2, 
    orders.bCity, 
    orders.bState, 
    orders.bZip, 
    orders.bCountry, 
    orders.sName, 
    orders.sStreet1, 
    orders.sStreet2, 
    orders.sCity, 
    orders.sState, 
    orders.sZip, 
    orders.sCountry, 
    orders.paymentType, 
    orders.invoiceNotes, 
    orders.pFee, 
    orders.shipping, 
    orders.tax, 
    orders.reasonCode, 
    orders.txnType, 
    orders.customerID, 
    customers.firstName AS firstName, 
    customers.lastName AS lastName, 
    customers.businessName AS businessName, 
    orderStatus.statusName AS orderStatus, 
    orderItem.fees + orders.shipping + orders.tax AS orderTotal, 
    orderItem.fees + orders.shipping + orders.tax - payments.amount AS orderBalance 
FROM orders 
LEFT JOIN customers ON orders.customerID = customers.id 
LEFT JOIN orderStatus ON orders.orderStatus = orderStatus.id
LEFT JOIN 
    ( 
      SELECT orderID, SUM(itemPrice * itemQuantity) as fees
      FROM orderItems
      GROUP BY orderID
    ) orderItems ON orderItems.orderID = orders.id 
LEFT JOIN 
    ( 
      SELECT orderID, SUM(amount) as amount
      FROM payments
      GROUP BY orderID
    ) payments ON payments.orderID = orders.id

使用GROUP BY

SELECT orders.billerID, 
    orders.invoiceDate, 
    orders.txnID, 
    orders.bName, 
    orders.bStreet1, 
    orders.bStreet2, 
    orders.bCity, 
    orders.bState, 
    orders.bZip, 
    orders.bCountry, 
    orders.sName, 
    orders.sStreet1, 
    orders.sStreet2, 
    orders.sCity, 
    orders.sState, 
    orders.sZip, 
    orders.sCountry, 
    orders.paymentType, 
    orders.invoiceNotes, 
    orders.pFee, 
    orders.shipping, 
    orders.tax, 
    orders.reasonCode, 
    orders.txnType, 
    orders.customerID, 
    customers.firstName AS firstName, 
    customers.lastName AS lastName, 
    customers.businessName AS businessName, 
    orderStatus.statusName AS orderStatus, 
    SUM(orderItems.itemPrice * orderItems.itemQuantity) + orders.shipping + orders.tax AS orderTotal, 
    SUM(orderItems.itemPrice * orderItems.itemQuantity) + orders.shipping + orders.tax - SUM(payments.amount) AS orderBalance 
FROM orders 
LEFT JOIN customers ON orders.customerID = customers.id 
LEFT JOIN orderStatus ON orders.orderStatus = orderStatus.id
LEFT JOIN orderItems ON orderItems.orderID = orders.id 
LEFT JOIN payments ON payments.orderID = orders.id
GROUP BY 
    orders.billerID, 
    orders.invoiceDate, 
    orders.txnID, 
    orders.bName, 
    orders.bStreet1, 
    orders.bStreet2, 
    orders.bCity, 
    orders.bState, 
    orders.bZip, 
    orders.bCountry, 
    orders.sName, 
    orders.sStreet1, 
    orders.sStreet2, 
    orders.sCity, 
    orders.sState, 
    orders.sZip, 
    orders.sCountry, 
    orders.paymentType, 
    orders.invoiceNotes, 
    orders.pFee, 
    orders.shipping, 
    orders.tax, 
    orders.reasonCode, 
    orders.txnType, 
    orders.customerID, 
    customers.firstName, 
    customers.lastName, 
    customers.businessName, 
    orderStatus.statusName  

GROUP BY解释:

您可以GROUP BY收集具有相似数据的记录。对于我的示例,我将使用包含CategoryNamePrice列的简单产品表。如果我按Category对数据进行分组,我可以基于任何其他列汇总(即SUMCOUNTMINMAX等) 。由于我按Category列进行分组,因此结果记录将具有Category的唯一值。任何其他列可能返回不同的值,因此不能包含在select语句中。

名称,类别,价格
青椒,辣椒,1.50
橙子辣椒,辣椒,2.50
黄椒,辣椒,2.50
柠檬,柑橘,1.00
橘子,柑橘,1.00
酸橙,柑橘,1.00

SELECT 
    Category, /* This is unique because it is in the GROUP BY clause */
    AVG(Price) AS AveragePrice,
    MAX(Price) AS MaxPrice,
    MIN(Price) AS MinPrice
    /* , Name */  /* This is invalid because it is not in the GROUP BY clause */
                  /* The values are not unique so SQL does not know what to return */
FROM Produce
GROUP BY Category
相关问题