我们经常会通过连接来对组合多个表的信息进行查询,常用的left join,right join, inner join,full join等等。刚刚在使用连接查询数据时,踩了个坑,这里进行总结下。
先说下踩的坑这个case吧,表A左连接表B,表A存储所有的关键词的pv信息,字段:keyword_id(关键词id), keyword_value(关键词字面量), keyword_pv(关键词pv);表B存储被认为作作弊流量的关键词pv信息,字段:keyword_id(关键词id),keyword_cheat_pv(关键词作弊pv), channel(关键词渠道)。
期望是通过连接来得出每个关键词的pv以及可能的作弊pv数目,所以采用左连接,以左表A为主。sql如下
select a.keyword_id, a.keyword_value, a.keyword_pv 'pv', if(b.keyword_cheat_pv is null, 0, b.keyword_cheat_pv) 'cheat_pv'
from A a left join B b on a.keyword_id = b.keyword_id
where b.channel = 1
查询结果却不符合预期,感觉像是以表B为基准了。查找了些资料才发现连接时,条件限制放在on还是where处要判断下。
on条件是在根据连接生成笛卡尔集时进行过滤的条件;where条件则是对经过连接后生成的临时表进行条件过滤。结合上面的case来看的话,在根据on条件生成了临时表后,再执行where过滤,那么就只会保留B中与A匹配的结果而且channel为1(因为匹配不成功的channel为null,不满足b.channel = 1这个条件)。所以sql修改为:
select a.keyword_id, a.keyword_value, a.keyword_pv 'pv', if(b.keyword_cheat_pv is null, 0, b.keyword_cheat_pv) 'cheat_pv'
from A a left join B b on a.keyword_id = b.keyword_id and b.channel = 1
把需要对右表的限制移到on中(右连接的话则相反),问题解决。