2015-04-14 53 views
1

我很努力地得到這個查詢的權利。每次我改變它,它都會破壞別的東西。如何糾正這個SQL查詢? SUM加入

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  | 
+----+------+-------+--------+ 
+1

請顯示一些樣品數據和所期望的結果。 – Barmar

+0

我已經添加了一個例子。 – Abs

+0

「產品」表中的user_id列在哪裏?不應該把它叫做'Products'就像在你的查詢中一樣? – Barmar

回答

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的車沒有完成的事務。

+0

這看起來不錯!我試圖用'IF'做類似的事情,但失敗了。我現在將檢查這個查詢。只有兩個小小的音符,'products.name'後面有一個額外的逗號,第四行應該說'transactions.id'。 – Abs

+0

這對我有用! – Abs

0

的IFNULL函數應該SUM函數內使用。

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 
+1

-1如果您有兩行值爲10和null的行,則它們的sum()將爲10. [SQL小提琴示例](http://sqlfiddle.com/#!9/37f1d/1/0) – Andomar

+0

是@Andomar是正確的,這是我面臨的問題。 – Abs

0

使用子查詢在CartTransactions之間執行INNER JOIN。這將擺脫引起額外總和的額外行。

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

+0

這也適用於我。但是,由於我擁有數百萬筆交易和數千種產品,查詢速度非常緩慢。一切都很好索引我認爲這可能是因爲子查詢。 – Abs

+0

如果Andomar的解決方案更有效率,那就去吧。 – Barmar