在 AWS Redshift 中透视非数字表

Posted

技术标签:

【中文标题】在 AWS Redshift 中透视非数字表【英文标题】:Pivoting a non-numeric table in AWS Redshift 【发布时间】:2015-11-20 18:44:54 【问题描述】:

我有一张亚马逊红移表格,我想沿一列旋转。例如

dim1  dim2  val
x     a     4s
x     b     5v
y     a     9l
y     b     3t

会变成:

dim1   a    b  
x      4s   5v
y      9l   3t

请注意,AWS Redshift 不支持数据透视、交叉表、未嵌套或案例扩展。此外,AWS 在https://forums.aws.amazon.com/thread.jspa?threadID=126369 中提出的解决方案还不够,因为它依赖于使用聚合函数,而且由于我的数据不包含数字,所以这不会可靠地工作(对吗?)。

我能想到的最佳解决方案是自我加入:

SELECT table.dim1, val as a, b
FROM table
WHERE dim2='a'
JOIN (
  SELECT dim1, val as b 
  FROM table
  WHERE dim2='b') AS t
ON t.dim1 = table.dim1

此解决方案的问题在于,您必须为 dim2 的每个可能值进行一次自连接,这很快就会变得难以管理,因为(在我的现实世界中)我的表非常巨大并且有 20 多个不同的值在dim2。对于dim2 中的每个新值,我必须进行另一个自我加入:

SELECT table.dim1, val as a, b, c
FROM table
WHERE dim2='a'
JOIN (
  SELECT dim1, val as b 
  FROM table
  WHERE dim2='b') AS t
ON t.dim1 = table.dim1
JOIN (
  SELECT dim1, val as c 
  FROM table
  WHERE dim2='c') AS t2
ON t2.dim1 = table.dim1

我们可以看到这会如何迅速失控。有没有更好的方法来做到这一点?

【问题讨论】:

【参考方案1】:

事实证明,AWS 的答案已经足够了,您可以使用 max() 对字符串进行聚合:

SELECT dim1, MAX(a) AS a, MAX(b) AS b
FROM (
  SELECT dim1, 
    CASE dim2 WHEN 'a' THEN val ELSE NULL END as a,
    CASE dim2 WHEN 'b' THEN val ELSE NULL END as b
  FROM table
)
GROUP BY dim1;

但是dim2 中有任意数量的值,这仍然很麻烦。我愿意接受更好的答案。

【讨论】:

没有数据透视表或交叉表这是我见过几次的解决方案 您可以根据需要删除ELSE NULL,这是默认选项。

以上是关于在 AWS Redshift 中透视非数字表的主要内容,如果未能解决你的问题,请参考以下文章

使用 Redshift (PostgreSQL) 和计数的数据透视表

AWS Redshift SQL - PIVOT 查询(一行/行多次计数)

将 Redshift 系统表的权限授予非超级用户

AWS Redshift 脚本导出

AWS Redshift:致命:非引导用户超出连接限制“500”

如何使用更改表查询在 AWS Redshift 中添加多列