表查询

现在就来讨论一下各种 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;