第26天: join _table

来源:互联网 发布:自制二维码软件 编辑:程序博客网 时间:2024/05/22 05:09

第26天:    join _table


a left outer join b  on a.id=b.id
and a.key =123 and  b.name =345;

hive只支持等连接,外连接,
左半连接,hive不支持非相等的join条件,
因为它很难在map/reduce job
实现这样的条件,而且,hive可以join两个以上的表。


写join查询时,有几个典型的点要考虑。
如下:
等连接
只有等连接才允许
select a.* from a join b  on (a.id=b.id)

不合法的情况如下:
select a.* from a join  b on (a.id != b.id);

写join查询时,有几个典型的点要考虑
如下:
多表连接
同个查询,可以jioin两个以上的表。
合法join

select a.val,b.val ,c.val
from   a join b on (a.key = b.key1)
join c  on (c.key =b.key2);

join的缓存和任务转换。。
hive转化多个表join时,如果每个表在join子句中。
使用的都是同一个列,只会转换为一个单独
的map/reduce
select a.val, b.val ,c.val
from a join b on (a.key =b.key1) join c
 on (c.key = b.key1);

 这个只会转换成单独的map/reduce任务。 只有b表
 的key1列在join被调用。

 另一方面
 select a.val, b.val ,c.val from a
 join b  on (a.key= b.key1 ) join
 c  on ( c.key =b.key2)
 两个map/reduce任务。
第一个MR : a和b 连接
第二个MR: 上面第一个MR的结果和C 连接

-----------------------------------
在jon 的每个MR ,序列中的最后一个表。
当其他被缓存时,他会流到reducers,所以
reducers需要缓存join关键字的特定值,组成的行,
通过组织最大的表,出现在序列的最后,
有助于减少reducers的内存。


select a.val, b.val ,c.val
from a join b on (a.key =b.key1) join c
 on (c.key = b.key1);

三个表,在同一个独立的map/reducer任务做join
a和b 的key对应的特定值,组成的行,会缓存在reducers的
内存,然后reducers接收c的每一行,和缓存的每一行做join
计算。

--------------------------------
重要
在join的每一个map/reduce阶段,
通过关键字,可以指定那个表从流接收。

select /*+ streamtable(a) */
a .val ,b.val, c.val
from a join b  on
(a.key =b.key1)
join c on (c.key = b.key1)

三个表的连接,会转换为一个map/reduce任务
reducer会把b和c的key的特定值,缓存在内存里面,
然后从流接收a的每一行, 和缓存的行做join

----------重要
join的结果
left right  full outer 连接
存在是为了提供on语句在没有匹配时,的更多控制,
例如:这个查询
select a.val ,b.val from a left outer join b
on  (a.key= b.key)

将会返回a的每一行,如果b.key 等于a.key
将会输出a.val ,b.val
如果a没有和b.key匹配的 行,
将会输出a.val ,null
如果b的行没有和a.key匹配上,
将被抛弃,语法
from a left outer  join b 必须写在一行,
为了理解它如何工作,--这个查询,a是b的左边
a的所有行会被保持, rigth outer join将
保持b的所有行,
full outer join 将会保存
a 和b的所有行, outer join 语义应该符合标准的sql
规范。。


----------重要
left semi join 实现了相关的 in/exists
的子查询语义的有效途径,
由于hive目前不支持in/exists的子查询。
所有你可以用left semi join重写你的子查询语句,
left semi join的限制是,

----------重要
join的过滤
也就是说,如果你在where子句中引用b的任何列
left outer 的部分join结果是不相关的,
所以当外连接时,使用这个语法
 select a.val, b.val from a left outer
 join b  on ( a.key=b.key, and b.ds = '2009-09-09'
  and a.ds ='2009-09-09')
  join的输出会预先过滤
  然后你不用对有a.key 而没有
  b.key的行做过滤,right 和full join也是
  一样的逻辑。


----------重要
select a.key ,a.value from  a
where a.key in (select b.key  from b)
 可以重写为
 select  a.key, a.val from a left semi join
 b on (a.key =b.key);



 
0 0
原创粉丝点击