hive Group By 语法

本文深入探讨了Hive中GROUP BY语句的用法,包括其基本概念、简单例子、高级特性如多组别插入、Map端聚合等。详细解释了如何根据性别计算去重用户数,以及在同一个查询中进行多个聚合操作的限制。同时,通过实例展示了如何在SQL查询中使用GROUP BY与聚合函数,确保了查询的有效性和准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

groupByClause: GROUP BY groupByExpression (, groupByExpression)*

groupByExpression: expression

groupByQuery: SELECT expression (, expression)* FROM src groupByClause?

 

简单例子

为了计算表的行数:

  SELECT COUNT(*) FROM table2;

 

根据性别,计算去重用户数,可以写下面的查询

  INSERT OVERWRITE TABLE pv_gender_sum
  SELECT pv_users.gender, count (DISTINCT pv_users.userid)
  FROM pv_users
  GROUP BY pv_users.gender;

同时可以做多个聚合操作,但是,不能有两个聚合操作有不同的DISTINCT列。下面的语句是合法的:

  INSERT OVERWRITE TABLE pv_gender_agg
  SELECT pv_users.gender, count(DISTINCT pv_users.userid), count(*), sum(DISTINCT pv_users.userid)
  FROM pv_users
  GROUP BY pv_users.gender;

但是,下面的查询是不允许的。不允许在同一个查询,有多个DISTINCT表达式

  INSERT OVERWRITE TABLE pv_gender_agg
  SELECT pv_users.gender, count(DISTINCT pv_users.userid), count(DISTINCT pv_users.ip)
  FROM pv_users
  GROUP BY pv_users.gender;

 

Select语句和group by字句

当使用group by字句,select语句,只能包含group by包含的列。当然,在select语句,可以有多个聚合函数(例如count)。看一下例子:

CREATE TABLE t1(a INTEGER, b INTGER);

一个关于上表的group by的查询,可以是这样:

复制代码
SELECT
   a,
   sum(b)
FROM
   t1
GROUP BY
   a;
复制代码

上面的查询可以工作,因为select字句包含a(group by表达式)和一个聚合函数(sum(b)).

但是,下面的查询无法工作:

复制代码
SELECT
   a,
   b
FROM
   t1
GROUP BY
   a;
复制代码

select语句有多余的列(b),它不包含在group by字句(而且它也不是聚合函数)。这是因为,如果表t1看起来像:

a    b
------
100  1
100  2
100  3

如果group的key是a,那么当group a=100时,b的值在hive中应该显示多少?一种说法,它应该是第一个值或最低值,但我们都同意,有多种可能的选项。hive摒弃了这种猜测无效的SQL(HQL,要准确):有一列在select子句中,却不包含在GROUP BY子句中。

 

高级特性

Multi-Group-By Inserts

简单查询或者聚合的输出,可以发送到多个表甚至是hadoop的dfs文件(可以使用hdfs工具管理)。例子,如果伴随着性别的细分,按年龄细分,人们需要根据这些,找到每个页面的访问量,使用下面的查询,可以做到这一点:

复制代码
  FROM pv_users 
  INSERT OVERWRITE TABLE pv_gender_sum
    SELECT pv_users.gender, count(DISTINCT pv_users.userid) 
    GROUP BY pv_users.gender 
  INSERT OVERWRITE DIRECTORY '/user/facebook/tmp/pv_age_sum'
    SELECT pv_users.age, count(DISTINCT pv_users.userid) 
    GROUP BY pv_users.age; 
复制代码

 

 

GroupBy的Map端聚合

hive.map.aggr控制如何聚合,默认是false,如果设置为true,Hive将会在map端做第一级的聚合。这通常提供更好的效果,但是要求更多的内存才能运行成功。

  set hive.map.aggr=true;
  SELECT COUNT(*) FROM table2;

翻译自 https://cwiki.apache.org/confluence/display/Hive/LanguageManual+GroupBy

### Hive中`DISTRIBUTE BY`语句的正确语法和使用顺序 #### 正确语法Hive查询语句中,`DISTRIBUTE BY`用于指定如何将数据分发到Reducer。其基本语法如下: ```sql SELECT column1, column2... FROM table_name [DISTRIBUTED BY (column_list)] [SORT BY column_list] [LIMIT number]; ``` 需要注意的是,`DISTRIBUTE BY`通常会与`SORT BY`一起使用来控制MapReduce作业中的分区和排序逻辑[^1]。 #### 使用顺序 按照Hive SQL的标准执行流程,各子句的处理顺序依次为:`FROM`, `WHERE`, `GROUP BY`, `HAVING`, `SELECT`, `DISTINCT`, `ORDER BY/SORT BY`, `LIMIT`。而`DISTRIBUTE BY`应当紧跟在`FROM`之后的数据源定义部分,并位于`SORT BY`之前。具体来说,在构建复杂的查询时,应遵循以下结构: - 数据来源 (`FROM`) - 过滤条件 (`WHERE`) - 聚合操作 (`GROUP BY`) 及过滤聚合后的结果(`HAVING`) - 选择字段 (`SELECT`) - 去重 (`DISTINCT`) - 分区 (`DISTRIBUTE BY`) - 排序 (`SORT BY`) - 结果截取 (`LIMIT`) 因此,`DISTRIBUTE BY`应该放置在整个查询接近尾部的位置,但在任何显式的全局排序指令如`ORDER BY`或局部排序指令如`SORT BY`之前。 #### 示例解释 下面给出一个具体的例子并加以说明: ```sql SELECT col1, SUM(col2) AS total_col2 FROM my_table GROUP BY col1 DISTRIBUTE BY col1 SORT BY col1 DESC; ``` 此SQL片段的作用是从表`my_table`读取数据,按列`col1`进行汇总计算得到每组内`col2`之和作为新列`total_col2`,接着依据`col1`值的不同把记录分配给不同的Reducer实例处理,最后在同一组内的输出上应用降序排列[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值