HIVE SQL 中 HQL 语句理解

这篇具有很好参考价值的文章主要介绍了HIVE SQL 中 HQL 语句理解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简介:

     HQL DQL指的是 数据查询语句, 主要是对 表数据进行查询操作的.

和mysql对比:

MySQL中 单表查询语句 完整格式如下:
    select distinct 列1, 列2... from 表名
    where 组前筛选
    group by 分组字段
    having 组后筛选
    order by 排序字段 [asc/desc]
    limit 起始索引, 数据条数;

Hive中 单表查询语句 完整格式如下:
    [CTE表达式]
    select distinct | all 列1,列2,....  from 表名

    where 组前筛选

    group by 分组字段

    having  组后筛选

    order by 排序字段 [asc | desc] 

    cluster by 分桶排序字段 | distribute by 分桶字段 sort by 排序字段

    limit 起始字段, 数据条数; 

HQL 和 MySQl的不同:

        1.HQL 可以支持 CTE表达式.

        2.HQL 筛选的时候可以写 all 或者 distinct

        3.HQL 支持分桶查询

 注意:

        distribute by 表示分桶, sort by表示桶内排序, 如果 分桶字段 和 排序字段是同一个字段, 则可以用cluster by实现.
        即: cluster by 分桶排序字段 = distribute by 分桶字段 + sort by 桶内排序字段

聚合, 分组查询:

-- 统计未支付、已支付各自的人数
select
       -- 方式1: case when 标准写法.
       case
           when isPay=0 then '未支付'
           when isPay=1 then '已支付'
       end isPay1,

       -- 方式2: case when 简化写法, 适用于 等于的判断
        case isPay
           when 0 then '未支付'
           when 1 then '已支付'
       end isPay2,

       count(orderNo) total_cnt
from orders group by isPay;

例:

-- 统计每个用户的平均订单消费额,过滤大于10000的数据
-- 细节: 因为 round() 对 avg()做了处理, 已经不是纯聚合函数了, 所以该字段(别名)放到having后报错.
-- 解决方案1: 直接把处理聚合函数的动作, 再写一份放到 having后, 即: 不采用别名的方式.
select
       userId,
       round(avg(realTotalMoney), 2) realTotalMoney_avg
from
     orders
group by
    userId
having round(avg(realTotalMoney), 2) > 10000;

-- 方式2: 子查询.
select * from (
    select
       userId,
       round(avg(realTotalMoney), 2) realTotalMoney_avg
    from
         orders
    group by
        userId
) t1 where realTotalMoney_avg > 10000;

-- 方式3: CTE表达式, 把结果临时用CTE存储, 然后再次查询.
with t1 as (
     select
       userId,
       round(avg(realTotalMoney), 2) realTotalMoney_avg
    from
         orders
    group by
        userId
)
select * from t1 where realTotalMoney_avg > 10000;

hive 中连接查询:

-- 3. hive中的连接查询(join)
-- 3.1 连接查询, inner join, 结果: 表的交集.
-- 显示内连接
select * from employee e1 inner join employee_address e2 on e1.id = e2.id;
-- inner 可以省略不写.
select * from employee e1 join employee_address e2 on e1.id = e2.id;

-- 隐式内连接
select * from employee e1, employee_address e2 where e1.id = e2.id;

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

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

-- 3.4 交叉连接查询, cross join, 结果: 表的笛卡尔积, 无意义, 了解即可, 一般不用.         以上四种, 和MySQL一样.
-- 笛卡尔积: 表A的总条数 * 表B的总条数
select * from employee e1 cross join employee_address e2;
select * from employee e1, employee_address e2;         -- 交叉查询的, 简化写法

-- 3.5 满外连接, full outer join, 结果: 左表全集 + 右表全集 + 表交集, 即: 满外连接 等价于 左外连接 + 右外连接
select * from employee e1 full outer join employee_address e2 on e1.id = e2.id;
-- outer可以省略不写
select * from employee e1 full join employee_address e2 on e1.id = e2.id;

-- 3.6 左半连接, left semi join, 结果: 表的交集, 只保留左表部分.
select * from employee e1 left semi join employee_address e2 on e1.id = e2.id;

分桶查询

分桶查询相关:
    1. 分桶 = 分文件, 如果创建分桶表, 添加数据的时候, 数据会根据 哈希取模法, 放到不同的桶(文件)中.
    2. 如果是分桶查询, 类似于 分组查询, 就是按照一定的条件, 把相同的数据(同一个桶的数据)放到一起的过程.
    3. 分桶查询格式如下:
        cluster by 分桶排序字段 = distribute by 分桶字段 + sort by 排序字段
    4. mapreduce.job.reduces参数的值默认是-1, 即: MR程序会根据任务量自动决定分成多少个桶,
       如果要手动指定桶的个数, 必须通过 set mapreduce.job.reduces = n; 参数实现.  

-- 1. 查询表数据, 这里我们用的是普通表 stu, 一样可以达到 分桶查询的目录, 因为分桶查询 类似于 分组查询, 就是把相同的数据放到一起而已.
select * from stu;

-- 2. 根据性别分桶查询, 分成2个桶.
select * from stu cluster by gender;

-- 3. 根据id分桶查询, 分成3个桶.
select * from stu cluster by id;        -- 没有达到分桶效果, 需要手动设置 reduce个数, 因为: 1个MR的分区 = 1个Hive的分桶 = 1个ReduceTask任务 = 1个结果文件.

-- 4. 解决上述的问题.
-- 手动设置ReduceTask任务数, 相当于设置了 桶的数量.
set mapreduce.job.reduces = 3;
-- 分桶查询.
select * from stu cluster by id;    -- 根据id分桶, 根据id排序(升序)

-- 根据id分桶, 根据年龄降序
select * from stu distribute by id sort by age desc;

-- 根据id分桶, 根据id升序
select * from stu distribute by id sort by id;      -- 等价于: select * from stu cluster by id;
-- select * from stu distribute by id sort by id desc order by name ;      -- 报错, sort by 和 order by冲突, 不能一起使用.

思考:


cluster by, distribute by, sort by, order by 它们之间的区别是什么?

答:   分桶查询 类似于 分组查询, 就是把相同的数据放到一起而已.

        distribute by 分桶 ,sort by 排序, 要是分桶字段和排序字段相同, 就相当于cluster by.

        sort by 分桶后排序, 而order by 属于全局排序,所以sort by 和 order by 冲突,不能一直使用.

 联合查询

  

联合查询解释:
    概述:
        联合查询指的是 union 查询, 目的: 达到类似于拼接表的操作, 把多张表拼接到一起.
    格式:
        select ... from ...
        union all / distinct
        select ... from ...
注意:
        1. 如果直接写union, 后边啥都不写, 默认是: union distinct
        2. union all是合并, 但是不去重.
           union distinct是合并, 但是去重.
        3. 要进行合并的表, 字段个数, 对应的数据类型必须保持一致.

-- 1. union all  合并, 不去重.
use day07;
select * from stu          -- 22条
union all
select * from stu_bucket;   -- 22条

-- 2. union distinct  合并, 去重.
select * from stu          -- 22条
union distinct
select * from stu_bucket;   -- 22条

-- 3. union 后边啥都不写, 默认是 union distinct
select * from stu          -- 22条
union
select * from stu_bucket;   -- 22条

-- 4. 验证: 合并的时候, 列的个数, 对应列的数据类型必须保持一致, 至于列名, 无所谓.
select * from stu       -- int, string, string, int, string
union
select * from employee;  -- int, string, string, int, string

-- 5. 细节, 如果向order by, group by, limit语句写到最后, 则是作用于 整个语句.
select * from stu                   -- 22条
union all
select * from stu_bucket limit 3;   -- 22条      最终结果: 3条

-- 6. 细节, 如果向order by, group by, limit语句写到某个语句后, 则是单独作用于: 该语句.
-- select * from (select * from stu limit 3) t1    -- 复杂写法, 可以这样写, 但是不推荐.
(select * from stu limit 3)                   -- 3条
union all
select * from stu_bucket ;   -- 22条           最终结果: 25条

随机抽样:

概述:
    它表示我们通过 tablesample()函数实现, 从大表中抽取出一定的样本数据.
格式:
    tablesample(bucket x out of y on 列名 或者 rand());
注意:
    1. y表示分成几个桶, 即: 桶的个数.
    2. x表示从桶内抽取x份(条)
    3. 根据列名抽取, 相当于把该列当做了分桶字段抽取, 列名一致的情况下, 其它条件不变(桶的数据等...), 每次抽取到的数据都一样.
    4. rand()表示随机数, 即随机抽取, 每次采集到的数据都不一样.
    5. x 不能比 y 大.

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

-- 2. 抽样查询, 根据列名抽取, 列名一致的情况下, 其它条件不变(桶的数据等...), 每次抽取到的数据都一样.
select * from stu tablesample ( bucket 1 out of 2 on gender);       -- 按照gender字段分成2个桶, 取第 1 份数据, 所有的女生
select * from stu tablesample ( bucket 2 out of 2 on gender);       -- 按照gender字段分成2个桶, 取第 2 份数据, 所有的男生
-- select * from stu tablesample ( bucket 3 out of 2 on gender);       -- 按照gender字段分成2个桶, 取第 3 份数据, 没有这样的数据, 报错.

-- 3. 随机采样, rand()表示随机数, 即随机抽取, 每次采集到的数据都不一样.
select * from stu tablesample ( bucket 1 out of 2 on rand());

虚拟列介绍:

概述:
    属于Hive内置的, 数据本身的参数, 辅助我们进行查询的.
分类:
    INPUT__FILE__NAME               显示数据行所在的 数据文件
    BLOCK__OFFSET__INSIDE__FILE     显示数据行所在的 数据文件中的 行偏移量(即: 起始索引)
        95001,李勇,男,20,CS    行偏移量(即: 起始索引): 0
        95002,刘晨,女,19,IS    行偏移量(即: 起始索引): 23
        95003,王敏,女,22,MA    行偏移量(即: 起始索引): 46
    ROW__OFFSET__INSIDE__BLOCK         显示数据所在的HDFS块的偏移量, 该虚拟列必须要设置才能用, 即:  set HIVE函数.exec.rowoffset=true。

        显示数据行 所在的 Block块的 编号(从 0 开始)
注意:
    1. 1个中文, gbk码表占2个字节, utf-8码表占3个字节
    2. row_offset_inside_block文章来源地址https://www.toymoban.com/news/detail-823825.html

select *, INPUT__FILE__NAME from stu;
select *, BLOCK__OFFSET__INSIDE__FILE from stu where BLOCK__OFFSET__INSIDE__FILE > 100;

SET hive.exec.rowoffset=true;      -- 开启器 hdfs块偏移量设置.
select *, ROW__OFFSET__INSIDE__BLOCK from stu;

到了这里,关于HIVE SQL 中 HQL 语句理解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Hive-SQL】Hive Select 选择语句排除一列或多列

    查看 除了sample_date 以外的所有字段信息 查看 除了sample_date 和 msgtype 以外的所有字段信息 上面的 set hive.support.quoted.identifiers=none; 可以替换操作: 在 \\\'hive-site.xml\\\' 中添加以下配置: hive.support.quoted.identifiers=none

    2024年02月10日
    浏览(28)
  • 关于hive sql进行调优的理解

            这是一个面试经常面的问题,很不幸,在没有准备的时候,我面到了这个题目,反思了下,将这部分的内容进行总结,给大家一点分享。         hive其实是基于hadoop的数据库管理工具,底层是基于MapReduce实现的,用户写的hivesql最终转换成MapReduce的任务运行在

    2024年02月11日
    浏览(43)
  • IDEA 运行hql 出现FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.mr.MapRedTas

    启用的hiveserver2 的模拟用户功能 ,依赖于Hadoop 提供的proxy user(代理用户功能),只有Hadoop中的代理用户才能模拟其他用户身份访问 Hadoop集群。 因此,需要将hiverserver2 的启动用户设置为 Hadoop 的代理用户 修改hadoop 配置文件 core-site.xml 添加如下配置 重启Hadoop 以及Hive 再次运

    2024年02月11日
    浏览(30)
  • Hive Sql 大全(hive函数,hive表)

    本节基本涵盖了Hive日常使用的所有SQL,因为SQL太多,所以将SQL进行了如下分类: 一、DDL语句(数据定义语句): 对数据库的操作:包含创建、修改数据库 对数据表的操作:分为内部表及外部表,分区表和分桶表 二、DQL语句(数据查询语句): 单表查询、关联查询 hive函数

    2024年02月19日
    浏览(34)
  • [hive] 在hive sql中定义变量

    在Hive SQL中,可以使用 SET 命令来定义变量。 变量可以用于存储和引用常量或表达式的值,以便在查询中重复使用。 下面是定义和使用变量的示例: 使用 SET 命令定义了一个名为 my_var 的变量, 在查询中使用 ${my_var} 引用变量。这样,变量的值将被替换为实际的字符串,从而

    2024年02月03日
    浏览(23)
  • 【大数据之Hive】十六、Hive-HQL函数之窗口函数(开窗函数)

      先定义了窗口的大小(按行来算),然后对窗口内的行的数据进行计算,再将计算结果返回给改行。   窗口函数包括窗口和函数两部分,窗口用于定义计算范围,函数用于定义计算逻辑,窗口函数只会在原来的表上增加一列结果列,不改变原来的数据。 函数:   绝

    2024年02月11日
    浏览(28)
  • 二百零九、Hive——with嵌套语句报错:hadoop.hive.ql.parse.SemanticException: Line 2:5 Ambiguous table alias ‘t2‘

    在Hive的with嵌套语句时,HQL报错Line 2:5 Ambiguous table alias \\\'t2\\\' org.apache.hadoop.hive.ql.parse.SemanticException: Line 2:5 Ambiguous table alias \\\'t2\\\' 看报错提示,Ambiguous table alias \\\'t2\\\',似乎是with嵌套子语句命名t2报错,但是我试了很多其他命名,都报类似的错误,如果大家知道原因的话还望告知,谢

    2024年01月20日
    浏览(30)
  • 【Hive】HQL Map 『CRUD | 相关函数』

    语法: map基本数据类型, 基本数据类型 注意是 ,不是 () 例子: 创建表时: 字段填充时: cast(null as mapstring, string) as XXX 没有删除,只能覆盖 只能 overwrite 覆盖 注意:如果查找不存在的键值对,会返回 null 值 map_keys(map_name) :获取该map的所有key,结果是一个Array。 map_keys(map

    2024年02月09日
    浏览(32)
  • 【Hive】HQL Array 『CRUD | 相关函数』

    语法: array基本数据类型 注意是 ,不是 () 例子: 创建表时: 字段填充时: cast(null as arraystring) as XXX 没有删除,只能覆盖 注意:数组越界会报错。 array() :创建一个数组。例如,array(1,2,3)将创建一个包含1、2、3三个元素的数组。 array_max(array) :返回数组中的最大值。例如,

    2024年02月11日
    浏览(24)
  • hive sql 和 spark sql的区别

    Hive SQL 和 Spark SQL 都是用于在大数据环境中处理结构化数据的工具,但它们有一些关键的区别: 底层计算引擎: Hive SQL:Hive 是建立在 Hadoop 生态系统之上的,使用 MapReduce 作为底层计算引擎。因此,它的执行速度可能相对较慢,尤其是对于复杂的查询。 Spark SQL:Spark SQL 则建

    2024年01月20日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包