HQL DQL语句基本查询

1.HQL DQL--基本查询

-- 1. 建库, 切库, 查表.
create database day08;
use day08;
show tables;

-- 2. 建表.
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';

-- 3. 上传源文件, 或者 load data方式加载数据.
-- 4. 查看表数据.
select * from orders;   -- 1000条

-- 5. 完成如下的需求.
-- 5.1 查询所有
select * from orders;   -- 1000条
select * from orders limit 100;   -- 10条, 实际开发中写法
-- 5.2 查询单列
select userName, orderId, totalMoney from orders;
-- 5.3 查询数据量
select count(orderId) from orders;        -- 1000条
-- 5.4 过滤广东省订单
select * from orders where userAddress like '广东省%';
-- 5.5 找出广东省单笔营业额最大的订单
-- 思路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 '广东省%');

-- 5.6 统计未支付、已支付各自的人数
-- 方式1: 分组统计.
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;

-- 思路1: if()函数直接实现.     if(判断条件, 值1, 值2);  条件成立返回值1, 不成立返回值2
select
    count(if(isPay = 0, isPay, null)) as `未支付`,
    count(if(isPay = 1, isPay, null)) as `已支付`
from orders;

-- 5.7 在已付款订单中,统计每个用户最高的一笔消费金额
select userId, max(realTotalMoney) from orders where isPay = 1 group by userId;
-- 5.8 统计每个用户的平均订单消费额
select userId, userName, avg(realTotalMoney) from orders  group by userId, userName;
-- 升级需求: 保留两位小数.
select userId, userName, round(avg(realTotalMoney), 2) as avg_money from orders  group by userId, userName;
-- 5.9 统计每个用户的平均订单消费额,过滤大于10000的数据
-- 细节: having后边可以跟聚合函数, 不能直接写其它的 数字函数.
select userId, userName, avg(realTotalMoney) as avg_money from orders  group by userId, userName having avg_money > 10000;
-- 四舍五入, 保留两位小数, 组后筛选, 写法如下.
select
    userId,
    userName,
    round(avg(realTotalMoney), 2) as avg_money
from
    orders
group by
    userId, userName
having
    round(avg(realTotalMoney), 2) > 10000;


-- 细节: 保留两位小数.
select round(10.123, 2);    -- 10.12
select round(10.125, 2);    -- 10.13

2.HQL DQL语句--join连接查询

-- join连接查询是多表查询的方式, 它具体有 6种查询方式, 分别是: 交叉连接, 内连接, 左外连接, 右外连接, 满外连接(全外连接), 左半连接, 具体如下:
-- 1. 建表, 上传源文件.
--table1: 员工表
CREATE TABLE employee(
   id int,      -- 员工id
   name string,
   deg string,
   salary int,
   dept string
 ) row format delimited fields terminated by ',';

--table2:员工家庭住址信息表
CREATE TABLE employee_address (
    id int,     -- 员工id
    hno string,
    street string,
    city string
) row format delimited fields terminated by ',';

-- 2. 查看表数据.
select * from employee;
select * from employee_address;

-- 3. 演示各种连接查询.
-- 3.1 交叉连接查询 cross join, 查询结果是: 两张表的笛卡尔积, 即: 表A总条数 * 表B总条数, 会有大量的脏数据, 一般不用.
-- 写法1: 标准写法.
select * from employee cross join employee_address;     -- 25条
-- 写法2: 语法糖
select * from employee, employee_address;     -- 25条

-- 3.2 内连接查询, inner join, 其中inner可以省略不写, 查询结果为: 表的交集.
-- 写法1: 标准写法.  显式内连接
select * from employee e1 inner join employee_address e2 on e1.id = e2.id;  -- 4条
select * from employee e1 join employee_address e2 on e1.id = e2.id;  -- 4条

-- 写法2: 语法糖, 隐式内连接.
select * from employee e1, employee_address e2 where e1.id = e2.id;  -- 4条

-- 3.3 左外连接查询, left outer join, 其中outer可以省略不写, 查询结果为: 左表的全集 + 表的交集.
select * from employee e1 left outer join employee_address e2 on e1.id = e2.id; -- 5条
select * from employee e1 left join employee_address e2 on e1.id = e2.id; -- 5条

-- 3.4 右外连接查询, right outer join, 其中outer可以省略不写, 查询结果为: 右表的全集 + 表的交集.
select * from employee e1 right outer join employee_address e2 on e1.id = e2.id; -- 5条
select * from employee e1 right join employee_address e2 on e1.id = e2.id; -- 5条

-- 3.5 满外连接(全外连接)查询, full outer join, 其中outer可以省略不写, 查询结果为: 左表全集 + 右表全集 + 表的交集.
-- 细节: 满外连接 = 左外连接 + 右外连接 查询结果.
select * from employee e1 full outer join employee_address e2 on e1.id = e2.id; -- 6条
select * from employee e1 full join employee_address e2 on e1.id = e2.id; -- 6条

-- 3.6 左半连接, left semi join, , 查询结果为: 表的交集.
-- 细节: 左半连接 相当于 内连接的查询结果, 只要左表部分.
select * from employee e1 left semi join employee_address e2 on e1.id = e2.id; -- 4条, 只有左表的数据.

3.HQL DQL语句--分桶查询

分桶查询介绍:
    概述:
        分桶查询就是根据分桶字段, 把表数据分成n份, 但是: 是逻辑划分, 不是物理划分.
        逻辑划分: 类似于分组, 就是根据分桶字段值 进行分组, HDFS上文件还是1个.
        物理划分: 就是昨天的分桶建表, HDFS上存储数据的时候, 已经变成了N个文件.
    格式:
        cluster by 分桶排序字段 | distribute by 分桶字段 sort by 排序字段 asc | desc
    细节:
        1. 分桶查询是 逻辑分桶, 把数据分成n组进行查询, 但是HDFS上还是1个文件.
           分桶建表是 物理分桶, 数据在HDFS上会被存储到N个文件几种.
        2. 分桶查询需要用到 set mapreduce.job.reduces = n; 这个n就是ReduceTask任务的数量, 即: 分几个桶.
        3. mapreduce.job.reduces 参数的值默认是 -1, 即: 程序会按照数据量, 任务量自动分配ReduceTask的个数, 一般是1个, 即: 1个桶.
        4. distribute by 表示分桶, sort by表示对桶内的数据进行排序(局部排序), 如果分桶字段和排序字段是同1个, 则可以简写为: cluster by
           即: cluster by = distribute by + sort by
        5. 面试题: cluster by, distribute by, sort by, order by这四组关键字的区别是什么?
            cluster by:     分桶且(桶内局部)排序的, 分桶字段和排序字段必须是同1个字段, 且是升序排列.
            distribute by:  仅分桶的, 一般要结合 set mapreduce.job.reduces = n;参数一起使用.
            sort by:        桶内排序(即: 局部排序), 一般要结合 distribute by 一起使用.
            order by:       全局排序的, 对全表数据进行排序, 和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;      -- 22条

-- 2. 按照性别进行分桶, 分成2个桶...
-- 核心细节, 分桶查询是, 需要设置ReduceTask的任务数, 有几个ReduceTask, 就有几个桶.
set mapreduce.job.reduces = 2;  -- 默认是-1, 即: 程序会根据数据量, 任务量, 自动给出 ReduceTask任务数, 一般是: 1
select * from student distribute by gender;        -- 根据gender分桶, 且根据gender升序排列.

-- 3. 按照id分成3个桶, 注意: 不排序.
set mapreduce.job.reduces = 3;
select * from student distribute by sid;

-- 4. 上述的数据, 虽然分成了3个桶, 但是不方便查看数据, 因此, 加入: 排序.
-- 按照id分成3个桶, 然后按照年龄降序排列.
select * from student distribute by sid sort by age;    -- 默认是升序.
select * from student distribute by sid sort by age desc;    -- 降序

-- 5. 如果分桶字段和排序字段是同1个, 则可以简写为: cluster by
-- 根据sid分成3个桶, 且根据sid升序排列.
select * from student distribute by sid sort by sid;    -- 默认是升序.
select * from student cluster by sid;       -- 效果同上.
-- select * from student cluster by sid desc;       -- 报错, cluster by默认升序.

4.HQL DQL--随机抽样

/*
随机抽样解释:
    概述:
        随机采样指的是 tablesample()函数, 通过它, 我们可以用 类似于分桶的思路, 对数据进行采样.
    格式:
        select .. from 表名 tablesample(bucket x out of y on 列名 | rand());
    格式解释:
        1. y表示: 把数据分成y个桶.   逻辑分桶.
        2. x表示: 从y个分桶中, 获取第x份数据.
        3. 如果是列名方式, 列名采样, 在列名等其它条件不发生改变的情况下, 每次采样获取的数据都是一样的.
        4. 如果是rand()函数, 随机采样, 则: 每次获取的数据都是不一样的.
        5. x 不能大于 y
*/
-- 1. 查看原表数据.
select * from student;      -- 22条, 12条男, 10条女

-- 2. 按照 性别分成2个桶, 取第1份数据.
select * from student tablesample ( bucket 1 out of 2 on gender);   -- 10条, 女
-- 3. 按照 性别分成2个桶, 取第2份数据.
select * from student tablesample ( bucket 2 out of 2 on gender);   -- 12条, 男

-- 4. 演示rand()函数
select rand();      -- 随机数, 生成0.0 ~ 1.0之间的数字, 包左不包右, 也叫: 前闭后开.  [0.0, 1.0)

-- 5. 随机采样, 分成3个桶, 取第1份数据.
select * from student tablesample ( bucket 1 out of 3 on rand());   -- 每次获取的数据条数都不一样.
select * from student tablesample ( bucket 4 out of 3 on rand());   -- 报错, x不能大于y

-- 也可以换成其它的表进行采样.
select * from orders tablesample ( bucket 1 out of 3 on rand());

  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃不到葡萄o

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值