Как группировать и считать в один ряд? - PullRequest
1 голос
/ 20 марта 2011

Для упрощения у меня есть древовидные таблицы: products, products-vs-orders, orders

  1. products поля: 'ProductID', 'Name', 'isGratis', ...
  2. products-vs-orders поля: 'ProductID', 'OrderID'
  3. orders поля: 'OrderID', 'Title', ...

На самом деле, у меня есть такой запрос:

SELECT orders.OrderID, orders.Title, COUNT(`products`.`isGratis`) AS "Quantity", `products`.`isGratis`
FROM `orders`, `products-vs-orders`, `products`
WHERE `orders`.`OrderID` = `products-vs-orders`.`OrderID` AND `products-vs-orders`.`ProductID` = `products`.`ProductID`
GROUP BY `products`.`PackID`, `products`.`isGratis`

Этот запрос работает и возвращает такой результат:

OrderID,    Title,      Quantity,   isGratis
1            My Order      20           0
1            My Order      3            1
2            An other      8            0
2            An other      1            1

Как я могу получить количество бесплатных продуктов?'и' оплачено 'для разделения cols?

OrderID,    Title,      Qt Paid,        Qt Gratis
1            My Order       20              3
2            An other       8               1

Ответы [ 3 ]

4 голосов
/ 20 марта 2011

Попробуйте это:

SELECT
    orders.OrderID,
    orders.Title, 
    COUNT(orders.OrderId) - SUM(`products`.`isGratis`) AS "Qt Paid", 
    SUM(`products`.`isGratis`) AS "Qt Gratis" 
WHERE `orders`.`OrderID` = `products-vs-orders`.`OrderID`
  AND `products-vs-orders`.`ProductID` = `products`.`ProductID`
GROUP BY `products`.`PackID`
1 голос
/ 20 марта 2011

SUM(products.isGratis) зависит от того факта, что логическое значение внутренне представлено базой данных как один числовой бит, поэтому false = 0 и true = 1.

Это может быть не так во ВСЕХ БДреализации.Следовательно, SUM над логическим полем может вызвать поведение, зависящее от реализации.

Преобразование логического значения в фактические значения 0 и 1 перед суммированием должно быть более правильным:

SELECT orders.OrderID, orders.Title, 
  SUM(CASE WHEN products.isGratis THEN 0 ELSE 1 END) AS "Qt Paid",
  SUM(CASE WHEN products.isGratis THEN 1 ELSE 0 END) AS "Qt Gratis"
FROM orders INNER JOIN `products-vs-orders` ON (orders.OrderID = `products-vs-orders`.OrderID)
  INNER JOIN products ON (`products-vs-orders`.ProductID = products.ProductID)
GROUP BY orders.OrderID, orders.Title
0 голосов
/ 20 марта 2011
select orderid,title,sum(if(isgratis=0,quantity,0)) as paid,sum(if(isgratis=1,quantity,0)) as gratis from ...
...