赞
踩
首先我们先知道HSQL的建表格式:
- -- 建表格式
- create [external] table [if not exists] 表名
- [(列名 数据类型 [comment 列描述信息], ......)]
- -- 默认是gbk码表,中文会乱码,需要改成utf8码表
- [comment 表的描述信息]
- [partitioned by (分区字段1 数据类型 [comment 描述信息],...... )]
- -- 分区=分文件夹 作用是避免全表扫描,降低扫描次数,提高查询效率
- [clustered by (分桶字段1,分桶字段2....) sorted by (排序字段1 asc|desc, 排序字段2 asc|desc, ....) into 桶的个数 buckets]
- -- 分桶=分文件 作用是减少笛卡尔积的数量,提高查询效率,方便数据采集
- [row format delimited|SerDe '指定其他的SerDe 类']
- -- 行格式切割符
- [stored as TextFile|Orc]
- -- 存储方式 行存储|列存储
- [location HDFS文件路径]
- -- 存储位置
- [tblproperties('属性名'='属性值')]
- -- 表属性信息 (内外部表,创建者信息,压缩协议.....)
MySQL 单表查询语法结构:
- -- MySQL单表查询语法
- select
- [distinct] 列名
- from 表名
- where 组前筛选
- group by 分组字段
- having 组后筛选
- order by 排序字段 asc| desc
- limit 起始索引,数据条数;
Hive 单表查询语法结构:
- -- Hive 单表查询语法结构
- [CTE 表达式]
- select
- [distinct | all] 列名
- from 表名
- where 组前筛选
- group by 分组字段
- having 组后筛选
- order by 排序字段 asc|desc
- cluster by 分桶排序字段 | distribute by 分桶字段 sort by 排序字段 asc| desc
- limit 起始索引,数据条数;
通过对比我们可以发现MySQL 和 Hive 单表查询有几点不同:
1. Hive 支持 CTE 表达式,可以临时存储某些语句的执行结果,方便查询.
2. Hive 除了有 distinct 关键字还支持 all 关键字写法.
3. Hive 支持分桶查询, cluster by + 分桶排序字段 (分桶排序必须是同一字段,且排序只能是升序),如果只分桶用 distribute by + 分桶字段 ,如果分桶和排序不是同一字段就用 distribute by + 分桶字段 sort by + 排序字段 asc | desc.
2.1 首先建表,上传数据,查询表中所有数据.
- -- 1. 建表.
- CREATE TABLE orders (
- orderId bigint COMMENT '订单id',
- orderNo string COMMENT '订单编号',
- shopId bigint COMMENT '门店id',
- userId bigint COMMENT '用户id',
- orderStatus tinyint COMMENT '订单状态 -3:用户拒收 -2:未付款的订单 -1:用户取消 0:待发货 1:配送中 2:用户确认收货',
- goodsMoney double COMMENT '商品金额',
- deliverMoney double COMMENT '运费',
- totalMoney double COMMENT '订单金额(包括运费)',
- realTotalMoney double COMMENT '实际订单金额(折扣后金额)',
- payType tinyint COMMENT '支付方式,0:未知;1:支付宝,2:微信;3、现金;4、其他',
- isPay tinyint COMMENT '是否支付 0:未支付 1:已支付',
- userName string COMMENT '收件人姓名',
- userAddress string COMMENT '收件人地址',
- userPhone string COMMENT '收件人电话',
- createTime timestamp COMMENT '下单时间',
- payTime timestamp COMMENT '支付时间',
- totalPayFee int COMMENT '总支付金额'
- ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
-
- -- 2. 上传源文件, 或者 load data方式加载数据.
- -- 3. 查看表数据.
- select * from orders;
2.2 查询前100条数据
- -- 查询前100条数据
- select * from orders limit 100;
2.3 查询单列数据
- -- 查询 userName, orderId, totalMoney 列的数据
- select userName, orderId, totalMoney from orders;
2.4 查询该数据的数据量
- -- 查询数据的数据量
- select count(orderId) from orders;
- -- orderId为主键列
2.5 过滤广东省的订单以及单笔营业额最大的订单
- -- 过滤广东省订单
- select * from orders where userAddress like '广东省%';
-
- --找出广东省单笔营业额最大的订单
- -- 此题可以有两种方法 可以进行排序或者子查询
-
- -- 方法1: 排序.
- select * from orders where userAddress like '广东省%' order by realTotalMoney desc limit 1;
- -- 此方法如果有并列的最大订单不能全部展示出来
- -- 方法2: 子查询.
- select *
- from
- orders
- where
- userAddress like '广东省%'
- and realTotalMoney = (select max(realTotalMoney) from orders where userAddress like '广东省%');
2.6 统计未支付和已支付的人各自多少人
- -- 统计未支付、已支付各自的人数
- -- 可以用两个函数来实现 分别是 case when 函数 和 if() 函数
-
- -- 方式1: 使用case when 函数
- select
- case
- when isPay = 0 then '未支付'
- when isPay = 1 then '已支付'
- end as isPay,
- case isPay
- when 0 then '未支付'
- when 1 then '已支付'
- end as isPay2,
- count(orderId)
- from
- orders
- group by
- isPay;
-
- -- 方式2: 使用 if() 函数
- select
- count(if(isPay = 0, isPay, null)) as `未支付`,
- count(if(isPay = 1, isPay, null)) as `已支付`
- from orders;
2.7 统计每个用户平均订单消费额且结果保留2位小数
- -- 统计每个用户平均订单消费额结果保留两位小数
- select userId, userName, round(avg(realTotalMoney), 2) as avg_money from orders group by userId, userName;
join 连接查询是多表查询的方式, 它具体有 6种查询方式, 分别是: 交叉连接, 内连接, 左外连接, 右外连接, 满外连接(全外连接), 左半连接.
cross join 交叉连接查询 , 查询结果是: 两张表的笛卡尔积 也就是 表A总条数 * 表B总条数, 会有大量的脏数据, 一般不用.
- -- 交叉连接 cross join
- select * from 表A cross join 表B;
(inner)join 内连接查询, 其中inner可以省略不写, 查询结果是: 表的交集.
- -- 内连接查询 (inner)join
-
- -- 方式1:显示内连接
- select * from 表A inner join 表B on 条件;
- select * from 表A join 表B on 条件;
-
- -- 方式2:隐式内连接 语法糖
- select * from 表A, 表B where 条件;
left (outer) join 左外连接查询, 其中outer可以省略不写, 查询结果是: 左表的全集 + 表的交集.
- -- 左外连接 left (outer) join
- select * from 表A left outer join 表B on 条件;
- select * from 表A left join 表B on 条件;
right (outer) join 右外连接查询, 其中outer可以省略不写, 查询结果是: 右表的全集 + 表的交集.
- -- 右外连接 right (outer) join
- select * from 表A right outer join 表B on 条件;
- select * from 表A right join 表B on 条件;
full (outer) join 满外连接(全外连接)查询, 其中outer可以省略不写, 查询结果是: 左表全集 + 右表全集 + 表的交集 也就是 左外连接 + 右外连接.
- -- 满外连接 full (outer) join
- select * from 表A full outer join 表B on 条件;
- select * from 表A full join 表B on 条件;
left semi join 左半连接, 查询结果为: 表的交集 也就是 内连接的查询结果只要左表部分.
- -- 左半连接 left semi join
- select * from 表A left semi join 表B on 条件;
分桶查询就是根据分桶字段, 把表数据分成n份.
- -- 格式
- cluster by 分桶排序字段 | distribute by 分桶字段 sort by 排序字段 asc | desc
分桶查询需要用到 set mapreduce.job.reduces = n; 这个n就是ReduceTask任务的数量 也就是: 分几个桶.
mapreduce.job.reduces 参数的值默认是 -1, 即: 程序会按照数据量, 任务量自动分配ReduceTask的个数, 一般是1个也就是 1个桶.
distribute by 表示分桶, sort by表示对桶内的数据进行排序(局部排序), 如果分桶字段和排序字段是同1个, 则可以简写为: cluster by.
1. 建表 上传源文件 查看数据
- -- 建表, 上传源文件, 查看表数据.
- create table student(
- sid int,
- name string,
- gender string,
- age int,
- major string
- ) comment '学生信息表'
- row format delimited fields terminated by ',';
- select * from student;
2. 按照性别进行分桶, 分成2个桶
- -- 按照性别进行分桶, 分成2个桶
- set mapreduce.job.reduces = 2;
- select * from student distribute by gender;
3. 按照id分成3个桶, 然后按照年龄降序排列
- -- 按照id分成3个桶, 然后按照年龄降序排列
- select * from student distribute by sid sort by age desc;
4. 根据sid分成3个桶, 且根据sid升序排列
- -- 根据sid分成3个桶, 且根据sid升序排列
- select * from student distribute by sid sort by sid;
- select * from student cluster by sid; -- cluster by 只能升序排列
随机采样指的是 tablesample()函数,类似于分桶的思路, 对数据进行采样.
- -- 格式
- select 列名 from 表名 tablesample(bucket x out of y on 列名 | rand());
- -- y表示: 把数据分成y个桶
- -- x表示: 从y个分桶中, 获取第x份数据
- -- x 不能大于 y
1. 根据上表 按照性别分成2个桶, 取第1份数据
- -- 按照性别分成2个桶, 取第1份数据
- select * from student tablesample ( bucket 1 out of 2 on gender);
2. 随机采样, 分成3个桶, 取第1份数据
- -- 随机采样, 分成3个桶, 取第1份数据
- select * from student tablesample (bucket 1 out of 3 on rand());
- -- 随机采样每次获取的数据都是不一样的
正则表达式不独属于任意的一种语言, 市场上绝大多数的语言都支持它.
正则的规则是通用的, 但是正则表达式的校验格式(语法)稍有不同.
. | 代表任意的1个字符 |
\. | 代表1个普通的. 没有任何的特殊含义 |
[abc] | 代表a,b,c中任意的1个字符 |
[^abc] | 代表除了a,b,c以外, 任意的1个字符 |
\d | 代表任意的1个数字, 等价于 [0-9] |
\w | 代表1个单词字符, 即: 数字, 字母, 下划线, 等价于: [a-zA-Z0-9_] |
\S | 代表任意的1个非空字符 |
\\ | 代表1个\ |
^ | 代表开头 |
$ | 代表结尾 |
? | 数量词, 代表前边的内容出现0次或者1次 |
* | 数量词, 代表前边的内容出现0次或多次 |
+ | 数量词, 代表前边的内容出现1次或者多次 |
a{n} | 数量词, 代表a恰好出现n次, 多一次少一次都不行 |
a{n,} | 数量词, 代表a至少出现n次, 至多出现无数次 |
a{n,m} | 数量词, 代表a至少出现n次, 至多出现m次, 包括n和m |
HiveSQL中, 正则校验格式为: 字符串 rlike '正则表达式'
例:校验手机号是否合法
- -- 校验手机号是否合法
- -- 规则: 1. 纯数字组成. 2.长度必须是11位. 3.第1位数字必须是1. 4.第2位数字可以是: 3-9
- select '13112345678' rlike '^1[3-9]\\d{9}$';
union 联合查询就是对表数据做纵向拼接.
union all 和 distinct 作用类似, 都是纵向合并, 区别就是: 去不去重的问题.
直接写union 默认是 union distinct, 即: 去重合并.
要进行union联合查询的数据, 列的个数, 对应的数据类型都要一致.如果条件写到上边的 查询语句后, 则: 单独作用于该SQL.
如果条件写到下边的 查询语句后, 则: 作用于全局.
1. union all 演示
- -- union all演示
- select * from 表A
- union all
- select * from 表B;
2. union distinct演示
- -- union distinct演示
- select * from 表A
- union distinct
- select * from 表B;
虚拟列是Hive内置的可以在查询语句中使用的特殊标记,可以查询数据本身的详细参数.
Hive目前可用3个虚拟列:
INPUT__FILE__NAME 显示数据行 所在的具体文件
BLOCK__OFFSET__INSIDE__FILE 显示数据行 所在文件的偏移量, 偏移量从0开始计数.
ROW__OFFSET__INSIDE__BLOCK 显示数据所在HDFS块的偏移量, 即: 该行数据在HDFS文件的那个Block块. 此虚拟列需要设置:SET hive.exec.rowoffset=true 才可使用
CTE 表达式也称公共表表达式, 就是用于临时存储某些结果数据的.
- -- 格式
- with CTE表达式的名字 as ( select 语句 )
- select ... from CTE表达式的名字;
1. 入门写法
- -- 入门写法
- with t1 as (
- select * from student
- )
- select * from t1;
2. from 风格
- -- from 风格
- with t1 as (
- select * from student
- )
- from t1 select sid, name;
3. 链式风格
- -- 链式风格
- with t1 as ( select * from student),
- t2 as ( select * from t1 limit 10),
- t3 as ( select sid, name, age from t2)
- select * from t3;
4. CTE结合union语句一起使用, 联合查询
- -- CTE结合union语句一起使用
- with t1 as ( select * from student),
- t2 as ( select * from t1 limit 10)
- select * from t1
- union all
- select * from t2;
5. 用数据表把 CTE 结果永久存储
- -- 用数据表把 CTE 结果永久存储
- create table tab1 as
- with t1 as (
- select * from student
- )
- select sid, name, age from t1 limit 10;
6. 用视图把 CTE 结果永久存储
- -- 用视图把 CTE 结果永久存储
- create view vi1 as
- with t1 as (
- select * from student
- )
- select sid, name, age from t1 limit 5;
-
今天的分享就到这里啦!有不同的意见可以私信哦!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。