我觉得可以看做select在having进行分组过滤前已经解析过,从而having可以使用select中的别名,下面这个例子可以明显看出。
要求:从电子商务行业中,取出每个城市的数据相关职位数量超过50的城市和职位数量
写法1:
select city,count(*) from dataanalyst
where industryField like '%电子商务%'
group by city
having count(*) >= 50;
写法2:
select city,count(*) from dataanalyst
group by city
having count(if(industryField like '%电子商务%',1,null)) >= 50;
明显看出结果错误,这是因为这里的count(*)统计的是城市所有行业的数据相关职位数量,而不仅是电子商务行业,然后就产生了select和having顺序的困惑
写法3:
select city,count(if(industryField like '%电子商务%',1,null)) as num from dataanalyst
group by city
having num >= 50;
而这种写法是正确的,统计的是电子商务行业相关的,问题来了,写法2和写法3区别在哪里,是在select语句中的count函数,写法2中select是用的count(*)但是用count(if(industryField like ‘%电子商务%’,1,null))进行的过滤,而写法3中select是用的后者以及用其进行过滤
写法2相当于在having中是电商行业进行过滤出城市列表,select先是统计所有行业结果,然后再选择having后的城市
写法2、3也说明了having可以使用select中的别名,select在having之前应该已经生成临时表,而且having中的count的临时表和select中count的临时表居然可以是不一样的,然后 用having的过滤结果对select临时表进行过滤(小声bb,我觉得在mysql中执行顺序可以看成from-where-group by-select-having-select-order by-limit)
结论:使用having时一定要注意和select中的某个聚合函数一样,且可以使用其别名