Есть ли лучший способ написать этот оператор SQL? - PullRequest
2 голосов
/ 20 февраля 2010

Я получаю и вычисляю некоторую базовую информацию о заказе в моем запросе 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 Ответ

2 голосов
/ 20 февраля 2010

GROUP BY, вероятно, позволит механизму SQL лучше оптимизировать ваш запрос, но затруднит его чтение из-за большого количества параметров группировки.

Другой вариант, рекомендованный SQL Team , - рассмотреть возможность использования подзапросов. Это часто может сделать операторы 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 собрать вместе записи, которые имеют схожие данные. Для моего примера я собираюсь использовать простую производственную таблицу со столбцами Category, Name и Price. Если я сгруппирую данные по Category, я смогу агрегировать (то есть SUM, COUNT, MIN, MAX и т. Д.) На основе любых других столбцов. Поскольку я группирую по столбцу Category, результирующие записи будут иметь уникальное значение для Category. Любой из других столбцов может возвращать другое значение и поэтому не может быть включен в оператор выбора.

Наименование, категория, цена
Зеленый перец, перец, 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...