2013-10-13 35 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)将统计订单表中包含条目的所有用户。 –