sql—使用impala按范围连接表的有效方法

1zmg4dgp  于 2021-06-26  发布在  Hive
关注(0)|答案(1)|浏览(468)

我有以下表格( Range )包括值范围和附加列:

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

这个 From 以及 Tobigint 而且是独家的。这个 Range 该表包括180万条记录。附加表( 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中进行更改吗?

hgc7kmma

hgc7kmma1#

以下解决方案的主要思想是将θ连接(非等连接)替换为等连接,这将导致良好的分布+高效的局部连接算法。
范围(-infinity,infinity)被拆分为 n 长度。
范围表中的每个范围都与其相交的部分相关联。
e、 g.给定n=1000,范围 [1652,3701] 将与节相关联 [1000,2000) , [2000,3000) 以及 [3000,4000) (将有3个记录,每个部分1个)

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

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

以同样的方式,values表中的值与包含它的范围相关联,例如。 2093 将与范围关联 [2000,3000) .
两个表之间的连接将基于表示节的值,例如。 [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 |
+------+-------+------------+----------+

相关问题