2013-10-13 38 views
0

爲了提高這個查詢的效率,我希望能夠消除嵌套的LEFT JOIN。我想過是否可以將COUNT(ActiveUsers)替換爲COUNT(DISTINCT IF(SUM(grand_total)>0,id,NULL)),以便我可以刪除LEFT JOIN,但是這似乎並沒有得到正確的結果。以下是我正在使用的原始代碼:代碼優化 - 刪除嵌套的左連接

SELECT 
COUNT(DISTINCT users.id) AS NumCustomer, 
COUNT(ActiveUsers) AS NumActiveCustomers, 
COUNT(ActiveUsers)/COUNT(DISTINCT username) AS CloseRate 
FROM users 
LEFT JOIN orders ON orders.userid = users.id 
LEFT JOIN (SELECT id AS ActiveUsers FROM users LEFT JOIN orders ON orders.userid = users.id GROUP BY id HAVING SUM(grand_total)>0) AS Active ON users.id = Active.ActiveUsers 
WHERE users.datecreated LIKE '2013%' 
GROUP BY YEAR(users.created), MONTH(users.created) 
ORDER BY YEAR(users.created), MONTH(users.created) 

有沒有辦法讓此代碼更有效?

+0

我不認爲你需要在訂單表上「LEFT JOIN」,因爲你希望grant_total的總和大於0。一個INNER JOIN應該可以工作 – AgRizzo

+2

首先發佈一個EXPLAIN輸出這裏和你的表結構和使用的存儲引擎.. –

+1

並用純英文重新定義你的SQL代碼你需要什麼.. –

回答

0

如果grand_total不能爲負數:

SELECT 
    COUNT(DISTINCT users.id) AS NumCustomer, 
    COUNT(distinct orders.userid) AS NumActiveCustomers, 
    COUNT(distinct orders.userid)/COUNT(DISTINCT users.username) AS CloseRate 
FROM users 
LEFT JOIN orders ON orders.userid = users.id 
WHERE users.datecreated LIKE '2013%' and grand_total>0 
GROUP BY YEAR(users.created), MONTH(users.created) 
ORDER BY YEAR(users.created), MONTH(users.created) 

(如果它不能爲零或者,那麼你並不需要第二個where條件。)

+0

嗯...是的。讓我試試這個。 COUNT(DISTINCT users.username)會統計所有用戶,然後COUNT(distinct orders.userid)將統計訂單表中包含條目的所有用戶。 –