如何将数组从两个不同的表列转换为并行行?

时间:2019-03-27 11:15:59

标签: sql hive

我正在使用 hive ,并且我有一个以下格式的表(我只显示一行,但是它有很多行)

_______________________________
segments | rates     | sessID
---------|-----------|---------
'1,2,3'  | '10,20,30'| 555

即,两列有一个字符串,表示相同长度的数组,第三列有一些整数。我想展平数组,以使第一个数组的第一个成员与第二个数组的第一个成员出现在同一行中,等等: 像这样:

----------------------------
segment | rate | sessId 
--------|------|------------
1       | 10   | 555
2       | 20   | 555
3       | 30   | 555

我尝试了以下查询(为简单起见,我为这些值进行了硬编码):

SELECT explode(segments), explode (rates), sessID FROM 
(SELECT Split('1,2,3', ',') as segments, Split('10,20,30', ',') as rates, 555 as sessID) data ;

但是,这确实会产生所需的结果,并返回错误:

失败:SemanticException 1:26 UDTF仅支持SELECT子句中的单个表达式。令牌“费率”附近遇到错误

当我尝试仅展平一列时,它确实起作用: 查询:

SELECT explode(segments) FROM (
SELECT Split('1,2,3', ',') as segments, Split('10,20,30', ',') as rates, 555 as sessID) data ;

结果:

1
2
3

如何获得想要的结果?

2 个答案:

答案 0 :(得分:0)

我无权使用Hive进行测试,但是方法 应该 基本可行。

POSEXPLODE()可用于获取两列,即数组内的位置和项目本身。然后您可以使用该位置从另一个数组中查找对应的项目...

SELECT
  yourData.sessID,
  segment.item                              AS segment,
  SPLIT(yourData.rates, ',')[segment.pos]   AS rate
FROM
  yourData
LATERAL VIEW
  POSEXPLODE(SPLIT(yourData.segments,',')) segment AS pos, item

认为 POSEXPLODE()返回从1开始的位置,但是Hive中的数组索引从0开始吗?如果是这种情况,请改用[segment.pos - 1]

答案 1 :(得分:0)

请尝试一下。

select sessID,tf1.val as segments, tf2.val as rates
  from (SELECT Split('1,2,3', ',') as segments, Split('10,20,30', ',') as rates, 555 as sessID) t
  lateral view posexplode(segments) tf1
  lateral view posexplode(rates) tf2
  where tf1.pos = tf2.pos;  

+---------+-----------+--------+--+
| sessid  | segments  | rates  |
+---------+-----------+--------+--+
| 555     | 1         | 10     |
| 555     | 2         | 20     |
| 555     | 3         | 30     |
+---------+-----------+--------+--+