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

Posted

技术标签:

【中文标题】如何将数组从两个不同的表列转换为平行行?【英文标题】:How to convert arrays from two different table columns to parallel rows? 【发布时间】:2019-03-27 11:15:58 【问题描述】:

我正在使用 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

我怎样才能得到我想要的结果?

【问题讨论】:

分段是否总是从 1 开始并从那里单调递增? 1,21,2,31,2,3,4 等?但从来没有 2,3,43,2,1?) 在没有更多信息的情况下,这可能会引导您朝着正确的方向前进:community.hortonworks.com/questions/65227/… 不,不确定值会增加。 【参考方案1】:

我无法访问 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]

【讨论】:

【参考方案2】:

请尝试一下。

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     |
+---------+-----------+--------+--+


【讨论】:

以上是关于如何将数组从两个不同的表列转换为平行行?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Azure SQL 将不同的表列合并为一个

如何使用java在mySql的表列中存储数组值

将 clob 数据插入不同的表列

Presto SQL - 两个完全不同的表连接平行而不是垂直

如何使用触发器从两个不同的表中插入数据

数据库表列行