如何重构此SQL查询?

时间:2009-12-14 02:21:16

标签: sql mysql

我有一个名为users的表,其中包含一个名为activated_at的列,我想通过检查列是否为空来计算已激活的用户数。然后像这样并排显示它们:

+----------+-----------+---------------+-------+
| Malaysia | Activated | Not Activated | Total |
+----------+-----------+---------------+-------+
| Malaysia |      5487 |           303 |  5790 | 
+----------+-----------+---------------+-------+

所以这是我的SQL:

select "Malaysia",
    (select count(*) from users where activated_at is not null and locale='en' and  date_format(created_at,'%m')=date_format(now(),'%m')) as "Activated",
    (select count(*) from users where activated_at is null and locale='en' and  date_format(created_at,'%m')=date_format(now(),'%m')) as "Not Activated",
    count(*) as "Total"
    from users 
    where locale="en"
    and  date_format(created_at,'%m')=date_format(now(),'%m');

在我的代码中,我必须指定所有where语句三次,这显然是多余的。我怎么能重构这个?

此致 MK。

3 个答案:

答案 0 :(得分:6)

不确定MySql是否支持CASE构造,但我通常通过做类似的事来处理这类问题,

select "Malaysia",
    SUM(CASE WHEN activated_at is not null THEN 1 ELSE 0 END) as "Activated",
    SUM(CASE WHEN activated_at is null THEN 1 ELSE 0 END as "Not Activated",
    count(*) as "Total"
from users 
where locale="en" and  date_format(created_at,'%m')=date_format(now(),'%m');

答案 1 :(得分:0)

SELECT 
    COUNT( CASE WHEN activated_at IS NOT NULL THEN 1 ELSE 0 END) as "Activated",
    COUNT( CASE WHEN activated_at IS NULL THEN 1 ELSE 0 END) as "Not Activated",
    COUNT(*) as "Total"
FROM users WHERE locale="en" AND date_trunc('month', now()) = date_trunc('month' ,created_at);

答案 2 :(得分:0)

我认为这样可行..但未经测试:

select "Malaysia",
    (select count(*) from users2 where activated_at is not null) as "Activated",
    (select count(*) from users2 where activated_at is null) as "Not Activated",
    count(*) as "Total"
    from (select * from users where locale='en' and  date_format(created_at,'%m')=date_format(now(),'%m')) users2

p / s:很高兴在这里见到另一位马来西亚人;)

编辑:那将无法工作..抱歉..使用其他人建议的情况..我希望我能删除这个答案..