表查询
现在就来讨论一下各种 Select 语句的使用。
排序与聚合
和普通的数据库相似, Hive 可以使用标准的 Order By 子句来对数据进行排序。 Order By 会对所有的输入进行一个单线程的全局排序,所以如果数据量比较大,效率会非常缓慢。所以当不需要对所有的数据进行排序时(多数情况下都不需要),可以使用 Hive 自己提供的非标准的 Sort By 来代替,他是依靠 reducer 来进行的排序。
有时候你可能想要控制特殊的一行进入特定的 reducer,而随后去执行一些聚合操作。就能够使用 Hive 的 Distrubute by 子句来完成。下面是一个例子,使用温度和年份来排序天气数据集,使用一种方式,使得对于指定的年份的所有行在相同的 reducer 分区中。
hive> From record2
> Select year, temperature
> Distrubute By year
> Sort By year Asc, temperature Desc;
1949 111
1949 78
1950 22
1950 0
1950 -11
然后后续的查询(或者嵌套了该语句的查询语句),就能使用在同一个文件中已经被分组并排好序的年份温度了。
如果 Sort By 与 Distribute 作用在相同的列上,可以使用 Cluster By 子句来代替他们。
MapReduce 脚本
就是使用 MapReduce 脚本程序(Python或者其他程序写的脚本)来完成一些查询任务。
貌似不太用,就先不写了。
Join
Hive 中的 Join 任务都是使用 MapReduce job 实现的。
Inner Joins
内连接,就是只列出连接后所有匹配的行。
一个小例子:先是两个表
hive (vaf)> select * from sales;
sales.name sales.tid
Joe 2
Hank 4
ALi 0
Eve 3
Hank 2
hive (vaf)> select * from things;
things.tid things.tname
2 Tie
4 Coat
3 Hat
1 Scarf
开始连接
Hive> Select sales.*, things.*
> From sales Join things On (sales.tid = things.tid);
也就是 Join On ,而且 On 之后的条件句可以多个条件, 用 And 来连接。
当然上面的连接可以直接使用下面的方式实现:
Select sales.*, things.*
From sales, things
Where sales.tid = things.tid;
不过这种方式貌似很费内存,一执行系统就自己掉了。
外连接
Hive> Select sales.*, things.*
> From sales Left Outer Join things On (sales.tid = things.tid);
Hive> Select sales.*, things.*
> From sales Right Outer Join things On (sales.tid = things.tid);
Left Outer Join 意思就是右边去找左边,没有找到的就为null
Right Outer Join 意思就是左边去找右边,没有找到的就为null
另外语句中有没有 Outer 是等价的。
Semi joins
考虑使用 In 关键字的语句。查询所有被购买的商品。
Select *
From things Where things.tid In (Select tid from sales);
他可以被表达为:
Select *
From things Left Semi Join sales On(sales.tid = things.tid);
这里有个限制就是必须遵守 Left Semi Join 的固定句式来查询。
Map Join
考虑刚才的语句
Hive> Select sales.*, things.*
> From sales Join things On (sales.tid = things.tid);
如果右表(things)足够小可以放进内存中。Hive 就可以将他加载进内存在各个 maper 中执行 Join 操作。 这就叫做一个 map join。
没有 reducer 来执行查询, 所以这个查询将不能在一个 Right 或者 Full Outer Join 上工作,因为他们都需要 reduce 端来对输出进行聚合。
Map join 在使用桶表的时候会得到很多的好处,因为一个 mapper 中的左表在的相同的桶中就能找到要关联的右表的数据。然而,要开启他,需要下面的配置:
set hive.optimize.bucketmapjoin=true;
子查询
Hive 中允许在 From 子句或者 Where子句中添加子查询。
下面的语句找出了每个天气记录站中每年最大气温的平均值。
Select station, avg(max_temperature)
From (
Select station, year, Max(temperature) As max_termperature
From records
Where temperature != 9999 And quality In (0,1,4,5,9)
Group By station, year
) mt
Group By station;
视图
概念不说了。
一个普通的视图
Create View valid_records
As
Select *
From records
Where temperature != 9999 And quality In (0,1,4,5,9);
为视图中的列进行重命名。
Create View max_temperatures(station, year, max_temperature)
As
Select station, year, Max(temperature)
From records
Where temperature != 9999 And quality In (0,1,4,5,9);
使用视图
Select station,year,Avg(max_temperature)
From max_temperatures
Gruop By station, year;