如何更正此SQL查询? SUM与JOIN

时间:2015-04-14 10:15:23

标签: mysql sql

我正在努力让这个查询正确。每当我改变它,它就会破坏别的东西。

SELECT products.id, 
products.name, 
COUNT(transactions.id) AS sales, 
IFNULL(SUM(cart.price_paid), 0) AS amount
FROM products
LEFT JOIN cart ON cart.product_id = products.id
LEFT JOIN transactions ON cart.transaction_id = transactions.id AND transactions.status = 'COMPLETED'
WHERE products.user_id = $id
AND products.active = 1
AND transactions.id IS NOT NULL
GROUP BY products.id

以上是试图让所有用户拥有的产品,无论他们是否有销售,然后展示它的销售。

目前,由于我有AND transactions.id IS NOT NULL,因此未显示所有产品。只有销售人员。如果我删除了这个,那么我会看到所有产品,但amount字段将不正确,因为金额会被夸大。

这些是一些基本的示例表:

# Products Table
+----+------+---------+--------+
| id | name | user_id | active |
+----+------+---------+--------+
|  1 | cup  |       4 |      1 |
|  2 | ball |       4 |      1 |
+----+------+---------+--------+

# Cart Table
+----+------------+----------------+-------------+
| id | product_id | transaction_id | Price_paid  |
+----+------------+----------------+-------------+
|  1 |          1 |              6 | 1.99        |
|  2 |          1 |              7 | 1.99        |
|  3 |          1 |              8 | 1.99        |
|  4 |          1 |              9 | 1.99        |
+----+------------+----------------+-------------+

# Transactions Table
+----+--------+-----------+
| ID | amount |  status   |
+----+--------+-----------+
|  6 | 1.99   | COMPLETED |
|  7 | 1.99   | COMPLETED |
|  8 | 2.99   | CREATED   |
|  9 | 2.99   | CREATED   |
+----+--------+-----------+

# Result    
+----+------+-------+--------+
| id | name | sales | amount |
+----+------+-------+--------+
|  1 | Cup  |     2 | 3.98   |
|  2 | Ball |     0 | 0      |
+----+------+-------+--------+

3 个答案:

答案 0 :(得分:3)

带有product列的user_id表非常奇怪。我可以看到购物车如何属于用户,但为什么产品属于用户?

对于您的查询,我想您只想对已售出的购物车price_paid求和。如果购物车已完成交易,则视为已售出。你可以这样做:

SELECT  products.id
,       products.name
,       COUNT(transactions.id) AS sales
,       SUM(CASE WHEN transactions.id IS NOT NULL THEN cart.price_paid END) AS amount
FROM    products
LEFT JOIN 
        cart 
ON      cart.product_id = products.id
LEFT JOIN 
        transactions 
ON      cart.transaction_id = transactions.id 
        AND transactions.status = 'COMPLETED'
WHERE   products.user_id = $id
        AND products.active = 1
GROUP BY
        products.id

CASE会在没有完成交易的情况下过滤掉price_paid购物车。

答案 1 :(得分:0)

应在SUM函数内部使用IFNULL函数。

Because 
    NULL+10 is null not 10, 
    IFNULL(NULL,0)+10 is 10

试试这个..

SELECT      products.id, 
            products.name, 
            COUNT(transactions.id) AS sales, 
            SUM(IFNULL(cart.price_paid, 0)) AS amount
FROM        products
LEFT JOIN   cart 
        ON  cart.product_id = products.id
LEFT JOIN   transactions 
        ON  cart.transaction_id = transactions.id 
        AND transactions.status = 'COMPLETED'
WHERE       products.user_id = $id
        AND products.active = 1
        AND transactions.id IS NOT NULL
GROUP BY products.id

答案 2 :(得分:0)

使用子查询在INNER JOINCart之间执行Transactions。这将消除导致额外总和的额外行。

SELECT products.id, products.name,
  COUNT(ct.product_id) AS sales,
  ROUND(IFNULL(SUM(ct.price_paid), 0), 2) AS amount
FROM products
LEFT JOIN 
    (SELECT product_id, transaction_id, price_paid
     FROM cart
     JOIN transactions ON cart.transaction_id = transactions.id 
     WHERE transactions.status = 'COMPLETED') AS ct
ON ct.product_id = products.id
WHERE products.user_id = 4
AND products.active = 1
GROUP BY products.id

DEMO