当前位置:  开发笔记 > 后端 > 正文

GROUP BY和LEFT JOIN与来自同一个表的COUNT

如何解决《GROUPBY和LEFTJOIN与来自同一个表的COUNT》经验,为你挑选了1个好方法。

想要按年份,类型和按月计算

这是我的user table:

id  type  uname      date_created
1    fac   a      2015-12-28 17:11:19
2    cs    b      2015-12-23 19:09:51
3    cs    c      2015-12-23 19:09:21
4    stu   d      2015-12-31 18:12:41
5    fac   e      2015-11-11 00:00:00
6    fac   f      2015-10-07 00:00:00

预期结果:

fac  stu  cs
 1    1    2 // month january
 1    0    0 // month octomber
 1    0    0 // month november

我尝试的是:

SELECT count(u1.id) as fac, count(u2.id) as stu, count(u3.id) as cs
FROM user u
left join user u1 ON u1.faculty = 'yes' AND YEAR(u1.date_created) = 2015
left join user u2 ON u2.faculty = 'no' AND YEAR(u2.date_created) = 2015
left join user u3 ON u3.faculty = 'club_student' AND YEAR(u3.date_created) = 2015
GROUP BY MONTH(u.date_created) ORDER BY MONTH(u.date_created)

给我错误的结果如:

fac  stu  cs
6    6    6 
6    6    6 
24   24   24

Felypp Olive.. 5

您需要的是一个PIVOT将行转换为列的命令.实际上,MySQL不支持这种操作,所以我们需要手动执行它CASE WHEN(参见SQLFiddle):

select 
  month(date_created) as month,
  count(case when faculty = 'yes' THEN 1 END) as fac,
  count(case when faculty = 'no'  THEN 1 END) as stu,
  count(case when faculty = 'club_student' THEN 1 END) as cs
from user
where 1=1
  and date_created >= STR_TO_DATE('01-01-2015','%d-%m-%Y')
  and date_created <  STR_TO_DATE('01-01-2016','%d-%m-%Y')
group by month(date_created)
order by month(date_created)

实际上,你的连接语法没有意义...你连接三次来计算每个表中的id ...从左连接开始,只有当连接匹配时才会返回这些表中的数据,如果不匹配则返回null ...在COUNT聚合函数中不计算空值,因此可以将连接语法简化为INNER连接语法.但是,INNER当您加入相同的表时,甚至不需要连接,并且实际上并不将FROM表中的任何列与表关联JOIN.

这样,您定义的过滤器可以简化为WHERE过滤器和CASE WHEN过滤器,如我所提议的那样.



1> Felypp Olive..:

您需要的是一个PIVOT将行转换为列的命令.实际上,MySQL不支持这种操作,所以我们需要手动执行它CASE WHEN(参见SQLFiddle):

select 
  month(date_created) as month,
  count(case when faculty = 'yes' THEN 1 END) as fac,
  count(case when faculty = 'no'  THEN 1 END) as stu,
  count(case when faculty = 'club_student' THEN 1 END) as cs
from user
where 1=1
  and date_created >= STR_TO_DATE('01-01-2015','%d-%m-%Y')
  and date_created <  STR_TO_DATE('01-01-2016','%d-%m-%Y')
group by month(date_created)
order by month(date_created)

实际上,你的连接语法没有意义...你连接三次来计算每个表中的id ...从左连接开始,只有当连接匹配时才会返回这些表中的数据,如果不匹配则返回null ...在COUNT聚合函数中不计算空值,因此可以将连接语法简化为INNER连接语法.但是,INNER当您加入相同的表时,甚至不需要连接,并且实际上并不将FROM表中的任何列与表关联JOIN.

这样,您定义的过滤器可以简化为WHERE过滤器和CASE WHEN过滤器,如我所提议的那样.

推荐阅读
Gbom2402851125
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有