开发者

How to group and count in one row?

To simplify, I have tree tables: products, products-vs-orders, orders

  1. products fields : 'ProductID', 'Name', 'isGratis', ...
  2. products-vs-orders fields : 'ProductID', 'OrderID'
  3. orders fields : 'OrderID', 'Title', ...

Actually, I have a query like this:

SELECT ord开发者_JAVA百科ers.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`

This query works and return this surch of result:

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

How can I retrieve the count of products 'gratis' and 'paid' in to separate cols ?

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


Try this:

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`


SUM(products.isGratis) depends on the fact that a boolean value is internally represented by the database as a single numeric bit, so false = 0 and true = 1.

This may not be the case in ALL DB implementations. Therefore, SUM over a boolean field may cause implementation-dependent behavior.

Converting the boolean into actual 0 and 1 values before summing should be more proper:

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


select orderid,title,sum(if(isgratis=0,quantity,0)) as paid,sum(if(isgratis=1,quantity,0)) as gratis from ...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜