循环并转置presto数组列

时间:2018-08-15 09:26:15

标签: sql presto

我的PrestoDB中有此行数组列,我想通过Redash(商业智能viz工具)进行查询并进行转置。让我在下面更好地说明我的观点:

原始数据:

id | array_col
--------------
1  | [[A,1],[B,2]]
2  | [[A,1]]

结果数据:

id  |  array_col_lbl1  |  array_col_val1  |  array_col_lbl2  |  array_col_val2
------------------------------------------------------------------------------
1   |         A        |         1        |        B         |        2

我尝试过的事情:

select
id
, array_col[0].lbl1 as array_col_lbl1
, array_col[0].val1 as array_col_val1
, array_col[1].lbl1 as array_col_lbl2
, array_col[1].val1 as array_col_val2
from mytable

很明显,我的方法不适用于仅包含单个元素的数组。它将引发Error running query: Array subscript out of bounds错误。

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

如果array_col的大小只能是固定的长度集,则此解决方案应为您工作。您需要知道的是Presto将始终尝试引发错误,而不是向您返回null。一种安全处理此问题的方法是通过在访问索引之前检查数组的大小(基数)。

SELECT 
  id
  , IF(CARDINALITY(array_column)>0, array_column[1][1], NULL) AS array_col_lbl1
  , IF(CARDINALITY(array_column)>0, array_column[1][2], NULL) AS array_col_val1
  , IF(CARDINALITY(array_column)>1, array_column[2][1], NULL) AS array_col_lbl2
  , IF(CARDINALITY(array_column)>1, array_column[2][2], NULL) AS array_col_val2
FROM mytable

如果您真的想对代码感到疑惑,Presto还支持“ TRY” UDF,该UDF将返回NULL而不是抛出错误。这样也可以:

SELECT 
  id
  , TRY(array_column[1][1]) AS array_col_lbl1
  , TRY(array_column[1][2]) AS array_col_val1
  , TRY(array_column[2][1]) AS array_col_lbl2
  , TRY(array_column[2][2]) AS array_col_val2
FROM mytable

尽管我不建议使用该解决方案,因为它可以掩盖您不希望发生的其他错误,这将使以后的调试成为噩梦。

如果表中的所有数组都可以具有任意长度的可变长度,那么我会尝试使用CROSS JOIN UNNEST进行其他选择 https://prestodb.io/docs/current/sql/select.html