如何在 AWS Athena 中将行转换为列?

Lou*_*uis 13 sql pivot amazon-web-services amazon-athena

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

但是,当我尝试时:

SELECT column1, column2, column3
FROM data
PIVOT
(
  MIN(column3)
  FOR column2 IN ('VALUE1','VALUE2','VALUE3','VALUE4')
)
Run Code Online (Sandbox Code Playgroud)

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

有谁知道如何在 AWS Athena 中完成我想要实现的目标?

Kri*_*öld 12

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

uid | key | value1 | value2
----+-----+--------+--------
 1  |  A  |  10    | 1000
 1  |  B  |  20    | 2000
 2  |  A  |  11    | 1001
 2  |  B  |  21    | 2001
Run Code Online (Sandbox Code Playgroud)

单列 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
) 
Run Code Online (Sandbox Code Playgroud)

结果:

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

Run Code Online (Sandbox Code Playgroud)

多列 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
) 
Run Code Online (Sandbox Code Playgroud)

结果:

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

Run Code Online (Sandbox Code Playgroud)

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

kad*_*ach 6

您可以PIVOT在 Athena 中使用map_agg.

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
Run Code Online (Sandbox Code Playgroud)

信用去这个网站。不幸的是,我还没有找到一种聪明的方法来以这种方式进行多列透视(我嵌套了查询,这并不漂亮)。


Res*_*hwa 2

我在使用 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           
Run Code Online (Sandbox Code Playgroud)