SQL语法好学,逻辑难学,特别是在一些业务场合下,稍有不慎数据就跑错了,为了避免这种尴尬,笔者整理一下工作中曾经遇到的各种坑,希望给各位看官一点参考。
1.一次left join统计pv出现的错误
- 需求概要
有两张业务表,一张存着用户的访问信息(table1),另一张存着用户的黑名单信息(table2),我们现在要统计用户排黑后的访问pv。 - 实现逻辑
table1 left join table2,然后count(userid)就能求出pv。写起来很简单,没有太多复杂的逻辑。 - 坑在哪儿呢?
left join
我们都知道left join是保留左表的所有字段,右表有匹配的话则写右表数据,没有匹配的话则写null,如果有重复匹配则存多条重复数据。
坑就在这,如果table2是按日期分期的,我们一次跑了七天的黑名单数据,但有的用户可能在好几天里都是黑名单用户,所以造成数据重复,这样left join以后的数据就会重复好多条,如果要求uv那么没问题,只要distinct一下就好了,但是pv的话就会有问题。 - 怎么解决呢
根据业务逻辑,首先对table2的userid进行去重,保证table2中的userid只出现一次,这样再统计pv就不会有问题了。 - 没理解怎么办
自己动手建一个table1 里边只存一个name字段,插入两条数据a,b
再建一个table2里边也只存一个name字段,插入五条数据,a,a,a,a,b
然后用table1 left join table2 然后count(table1.name)试一下。
2.hive -e报错
报错是cant recoginize at line 2巴拉巴拉的
然后思来想去想不明白是怎么回事,后来在网上看到有人说,是windows和unix的行尾结束符问题。
修改方法是:
打开notepad++ 点击编辑 行尾显示符 转换为unix然后就ok了。
3.聚合函数+over()统计的误区
聚合函数就是sum(),avg(),count()等等,这个是一个非常容易忽略的点,如果不注意很容易出题。
建表语句不说了,直接给出数据格式:
数据结构
分四种情况
- 不带orderby
select FName,Fcity,FAge,FSalary,
sum(FSalary) over(partition by Fcity) '到当前行工资求和'
from over2;
结果
可以看出是对分区里的所有数据进行计算。
- 带order by
select FName,Fcity,FAge,FSalary,
sum(FSalary) over(partition by Fcity order by FSalary) '到当前行工资求和'
from over2;
结果
可以看出是到当前行的累计聚合结果,注意如果出现数据相同情况,则共享同一个累计结果。
这个就是order by 的作用。
- 带order by 和 rows between
select FName,Fcity,FAge,FSalary,
sum(FSalary) over(order by FSalary rows between unbounded preceding and current row) '到当前行工资求和'
from over2;
结果
可以看出即使数据相同也没有共享数据同一个聚合结果。
- 带order by和range between
select FName,Fcity,FAge,FSalary,
sum(FSalary) over(order by FSalary range between unbounded preceding and current row) '到当前行工资求和'
from over2;
结果
和第二种情况是一模一样的。
网友评论