如何将行转入 AWS Athena 中的列?

Posted

技术标签:

【中文标题】如何将行转入 AWS Athena 中的列?【英文标题】:How to pivot rows into columns in AWS Athena? 【发布时间】:2018-06-09 08:13:23 【问题描述】:

我是 AWS Athena 的新手,并试图将一些行转换为列,类似于此 *** post 中的最佳答案。

但是,当我尝试时:

SELECT column1, column2, column3
FROM data
PIVOT
(
  MIN(column3)
  FOR column2 IN ('VALUE1','VALUE2','VALUE3','VALUE4')
)

我收到错误: mismatched input '(' expecting ',', ')' (service: amazonathena; status code: 400; error code: invalidrequestexception

有人知道如何在 AWS Athena 中实现我想要实现的目标吗?

【问题讨论】:

【参考方案1】:

我在使用 PIVOT 函数时遇到了同样的问题。不过我用了一个转机的方式来获取一个类似格式的数据集:

select 
  columnToGroupOn,
  min(if(colToPivot=VALUE1,column3,null)) as VALUE1, 
  min(if(colToPivot=VALUE2,column3,null)) as VALUE2, 
  min(if(colToPivot=VALUE3,column3,null)) as VALUE3 
from
    data
group by columnToGroupOn           

【讨论】:

我认为您应该使用“max”而不是“min”,因为在“if”表达式中,对于不匹配的行,您会返回 0。 是的,你是对的,但是 OP 需要一个获取 min(column3) 的解决方案,而使用 max 则相反。我认为正确的解决方案是使用 null 而不是 0 作为默认值。更正了我的答案。【参考方案2】:

您可以使用 map_agg 在 Athena 中创建单列 PIVOT

SELECT
  uid,
  kv['c1'] AS c1,
  kv['c2'] AS c2,
  kv['c3'] AS c3
FROM (
  SELECT uid, map_agg(key, value) kv
  FROM vtable
  GROUP BY uid
) t

归功于this website。不幸的是,我还没有找到一种巧妙的方法来以这种方式进行多列旋转(我嵌套了查询,这并不漂亮)。

【讨论】:

这很有帮助。谢谢你。我想补充一点,map_agg() 函数中的键和值参数将是您要扩展的现有列,值将是与该列关联的值。例如键 = 物种,值 = 计数。 该网址现已弃用,您可以尝试this website 获取文档。【参考方案3】:

扩展@kadrach 的答案。 假设这样的表

uid | key | value1 | value2
----+-----+--------+--------
 1  |  A  |  10    | 1000
 1  |  B  |  20    | 2000
 2  |  A  |  11    | 1001
 2  |  B  |  21    | 2001

单列 PIVOT 是这样工作的

SELECT
  uid,
  kv1['A'] AS A_v1,
  kv1['B'] AS B_v1
FROM (
  SELECT uid, map_agg(key, value1) kv1
  FROM vtable
  GROUP BY uid
) 

结果:

uid | A_v1 | B_v1 
----+------+-------
 1  |  10  |  20   
 2  |  11  |  21  

多列 PIVOT 是这样工作的

SELECT
  uid,
  kv1['A'] AS A_v1,
  kv1['B'] AS B_v1,
  kv2['A'] AS A_v2,
  kv2['B'] AS B_v2
FROM (
  SELECT uid,
      map_agg(key, value1) kv1,
      map_agg(key, value2) kv2
  FROM vtable
  GROUP BY uid
) 

结果:

uid | A_v1 | B_v1 | A_v2 | B_v2 
----+------+------+------+-----
 1  |  10  |  20  | 1000 | 2000
 2  |  11  |  21  | 1001 | 2001

【讨论】:

这是否意味着我必须提前知道key 列中的所有唯一值? 不幸的是,这种方法是可以的。当然可能有更通用的解决方案(例如使用连接),但我还没有创建它的需要。 我试图找到一个通用的解决方案,它允许根据值动态创建列数 - 但 presto 似乎没有提供这样的东西。我的解决方法是根据初始查询的结果动态创建相应的 SQL。但这总是被证明太麻烦了,在我们的例子中,我们总是新的几个可能的值。

以上是关于如何将行转入 AWS Athena 中的列?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取输入文件名作为 AWS Athena 外部表中的列

无法访问 AWS Athena 中的数组元素

AWS Athena (Presto) - 如何将时间戳格式化为日期格式?

如何把域名转入GoDaddy?转移到GoDaddy有啥好处?

C语言编程中如何将一个文件中的信息转入到另一个文件

如何处理 AWS Athena 中同一列中只有日期 (%m-%d-%Y) 和日期时间 ('%m-%d-%Y %H:%i') 记录的列?