2017-02-22 36 views
2

加入由範圍表有效途徑我有下表中的第一個(Range)包括值和其他列的範圍:使用帕拉

row | From | To  | Country .... 
-----|--------|---------|--------- 
1 | 1200 | 1500 | 
2 | 2200 | 2700 | 
3 | 1700 | 1900 | 
4 | 2100 | 2150 | 
... 

FromTobigint和是互斥的。 Range表包括1.8M記錄。 附加表(Values)包含270萬條記錄,看起來像:

row  | Value | More columns.... 
--------|--------|---------------- 
    1 | 1777 |  
    2 | 2122 |  
    3 | 1832 |  
    4 | 1340 |  
    ... 

我想創建一個表如下:

row  | Value | From | To | More columns.... 
--------|--------|--------|-------|--- 
    1 | 1777 | 1700 | 1900 | 
    2 | 2122 | 2100 | 2150 | 
    3 | 1832 | 1700 | 1900 | 
    4 | 1340 | 1200 | 1500 | 
    ... 

我用BETWEEN針對上述任務,但從未查詢結束於:

VALUES.VALUE between RANGE.FROM and RANGE.TO 

我需要在表分區或Impala中進行更改嗎?

+1

待接合它的 「使用盡可能多的關鍵字,可能表定義」 挑戰的一部分? –

回答

2

以下解決方案的主要思想是用equi連接替換theta連接(非等連接),這將導致良好的分佈+有效的本地連接算法。

範圍(-infinity,infinity)被分割爲長度爲n的部分。
範圍表中的每個範圍都與其相交的部分相關聯。

例如給定的n = 1000的範圍內,[1652,3701]將與區段[1000,2000)[2000,3000)[3000,4000)(和將有3條記錄,1爲每個部分)

   1652    3701 
       |     | 
       ------------------- 

------------------------------------------------------- 
|  |  |  |  |  |     
0  1000  2000  3000  4000  5000 

以相同的方式從這些值中的表的值是相關聯與包含它的範圍相關聯,例如2093將與範圍[2000,3000)相關聯。

2個表格之間的連接將取決於表示該部分的值,例如, [1652,3701]2093打算在部分[2000,3000)


create table val_range (id int,from_val bigint,to_val bigint); 

insert into val_range values 
    (1,1200,1500) 
    ,(2,2200,2700) 
    ,(3,1700,1900) 
    ,(4,2100,2150) 
; 

create table val (id int,val bigint); 

insert into val values 
    (1,1777)  
    ,(2,2122)  
    ,(3,1832)  
    ,(4,1340) 
; 

set n=1000; 

select  v.id 
      ,v.val 
      ,r.from_val 
      ,r.to_val 

from  (select r.* 
        ,floor(from_val/${hiveconf:n}) + pe.i as match_val 

      from val_range r 
        lateral view posexplode 
            (
             split 
             (
              space 
              (
               cast 
               (
                floor(to_val/${hiveconf:n}) 
                - floor(from_val/${hiveconf:n}) 

                as int 
               ) 
              ) 
              ,' ' 
             ) 
            ) pe as i,x 
      ) r 

      join val v 

      on  floor(v.val/${hiveconf:n}) = 
        r.match_val 

where  v.val between r.from_val and r.to_val 

order by v.id   
; 

+------+-------+------------+----------+ 
| v.id | v.val | r.from_val | r.to_val | 
+------+-------+------------+----------+ 
| 1 | 1777 |  1700 |  1900 | 
| 2 | 2122 |  2100 |  2150 | 
| 3 | 1832 |  1700 |  1900 | 
| 4 | 1340 |  1200 |  1500 | 
+------+-------+------------+----------+ 
+0

謝謝Dudu!你能否給你的解決方案添加一點解釋? – Avi

+0

我會的,但你應該知道這是一個蜂巢解決方案 –

+0

謝謝,我看到了。我可以與Hive或Impala一起工作。 Impala更可取,但如果它在Hive中有效,我只能在Hive中使用它。 – Avi