阅读本文小建议:本文适合细嚼慢咽,不要一目十行,否则会错过不少有价值的细节。sql
文章首发于公众号:五分钟学大数据数据库
在进行数仓搭建和数据分析时最经常使用的就是 sql,其语法简洁明了,易于理解,目前大数据领域的几大主流框架所有都支持sql语法,包括 hive,spark,flink等,因此sql在大数据领域有着不可替代的做用,须要咱们重点掌握。框架
在使用sql时若是不熟悉或不仔细,那么在进行查询分析时极容易出错,接下来咱们就来看下几个容易出错的sql语句及使用注意事项。函数
hive 除了支持 int,double,string等经常使用类型,也支持 decimal 类型,用于在数据库中存储精确的数值,经常使用在表示金额的字段上大数据
注意事项:spa
如:decimal(11,2) 表明最多有11位数字,其中后2位是小数,整数部分是9位;
若是整数部分超过9位,则这个字段就会变成null,若是整数部分不超过9位,则原字段显示;
若是小数部分不足2位,则后面用0补齐两位,若是小数部分超过两位,则超出部分四舍五入;
也可直接写 decimal,后面不指定位数,默认是 decimal(10,0) 整数10位,没有小数code
表建立的时候能够用 location 指定一个文件或者文件夹 create table stu(id int ,name string) location '/user/stu2';
注意事项:ci
建立表时使用location,
当指定文件夹时,hive会加载文件夹下的全部文件,当表中无分区时,这个文件夹下不能再有文件夹,不然报错。
当表是分区表时,好比 partitioned by (day string), 则这个文件夹下的每个文件夹就是一个分区,且文件夹名为 day=20201123
这种格式,而后使用:msck repair table score; 修复表结构,成功以后便可看到数据已经所有加载到表当中去了数据分析
从hdfs上加载文件 load data inpath '/hivedatas/techer.csv' into table techer; 从本地系统加载文件 load data local inpath '/user/test/techer.csv' into table techer;
注意事项:string
删除表操做 drop table score1; 清空表操做 truncate table score2;
注意事项:
若是 hdfs 开启了回收站,drop 删除的表数据是能够从回收站恢复的,表结构恢复不了,须要本身从新建立;truncate 清空的表是不进回收站的,因此没法恢复truncate清空的表。
因此 truncate 必定慎用,一旦清空除物理恢复外将无力回天
INNER JOIN 内链接:只有进行链接的两个表中都存在与链接条件相匹配的数据才会被保留下来 select * from techer t [inner] join course c on t.t_id = c.t_id; -- inner 可省略 LEFT OUTER JOIN 左外链接:左边全部数据会被返回,右边符合条件的被返回 select * from techer t left join course c on t.t_id = c.t_id; -- outer可省略 RIGHT OUTER JOIN 右外链接:右边全部数据会被返回,左边符合条件的被返回、 select * from techer t right join course c on t.t_id = c.t_id; FULL OUTER JOIN 满外(全外)链接: 将会返回全部表中符合条件的全部记录。若是任一表的指定字段没有符合条件的值的话,那么就使用NULL值替代。 SELECT * FROM techer t FULL JOIN course c ON t.t_id = c.t_id ;
注意事项:
注意:表之间用逗号(,)链接和 inner join 是同样的,例:
select tableA.id, tableB.name from tableA , tableB where tableA.id=tableB.id; 和 select tableA.id, tableB.name from tableA join tableB on tableA.id=tableB.id;
它们的执行效率没有区别,只是书写方式不一样,用逗号是sql 89标准,join 是sql 92标准。用逗号链接后面过滤条件用 where ,用 join 链接后面过滤条件是 on。
为何把这个单独拿出来讲,由于它和其余的 join 语句不太同样, 这个语句的做用和 in/exists 做用是同样的,是 in/exists 更高效的实现 SELECT A.* FROM A where id in (select id from B) SELECT A.* FROM A left semi join B ON A.id=B.id 上述两个 sql 语句执行结果彻底同样,只不过第二个执行效率高
注意事项:
hive支持 count(),max(),min(),sum(),avg() 等经常使用的聚合函数
注意事项:
聚合操做时要注意 null 值:
count(*) 包含 null 值,统计全部行数;
count(id) 不包含id为 null 的值;
min 求最小值是不包含 null,除非全部值都是 null;
avg 求平均值也是不包含 null。
以上须要特别注意,null 值最容易致使算出错误的结果
hive 中支持经常使用的算术运算符(+,-,*,/) 比较运算符(>, <, =) 逻辑运算符(in, not in) 以上运算符计算时要特别注意 null 值
注意事项:
id | price | dis_amount |
---|---|---|
1 | 100 | 20 |
2 | 120 | null |
各字段含义: id (商品id)、price (价格)、dis_amount (优惠金额)
我想算每一个商品优惠后实际的价格,sql以下:
select id, price - dis_amount as real_amount from product;
获得结果以下:
id | real_amount |
---|---|
1 | 80 |
2 | null |
id=2的商品价格为 null,结果是错误的。
咱们能够对 null 值进行处理,sql以下:
select id, price - coalesce(dis_amount,0) as real_amount from product; 使用 coalesce 函数进行 null 值处理下,获得的结果就是准确的 coalesce 函数是返回第一个不为空的值 如上sql:若是dis_amount不为空,则返回dis_amount,若是为空,则返回0
小因而不包含 null 值,如 id < 10;是不包含 id 为 null 值的。
not in 是不包含 null 值的,如 city not in ('北京','上海'),这个条件得出的结果是 city 中不包含 北京,上海和 null 的城市。
在sql语句的过滤条件或运算中,若是有多个条件或多个运算,咱们都会考虑优先级,如乘除优先级高于加减,乘除或者加减它们之间优先级平等,谁在前就先算谁。那 and 和 or 呢,看似 and 和 or 优先级平等,谁在前先算谁,可是,and 的优先级高于 or。
注意事项:
例:
仍是一张商品表(product)
id | classify | price |
---|---|---|
1 | 电器 | 70 |
2 | 电器 | 130 |
3 | 电器 | 80 |
4 | 家具 | 150 |
5 | 家具 | 60 |
6 | 食品 | 120 |
我想要统计下电器或者家具这两类中价格大于100的商品,sql以下:
select * from product where classify = '电器' or classify = '家具' and price>100
获得结果
id | classify | price |
---|---|---|
1 | 电器 | 70 |
2 | 电器 | 130 |
3 | 电器 | 80 |
4 | 家具 | 150 |
结果是错误的,把全部的电器类型都查询出来了,缘由就是 and 优先级高于 or,上面的sql语句实际执行的是,先找出 classify = '家具' and price>100 的,而后在找出 classify = '电器' 的
正确的 sql 就是加个括号,先计算括号里面的:
select * from product where (classify = '电器' or classify = '家具') and price>100
第一时间获取最新大数据技术,尽在公众号:五分钟学大数据
搜索公众号:五分钟学大数据,学更多大数据技术!
扫码关注