在AWS Redshift

时间:2015-11-20 18:44:55

标签: sql postgresql pivot crosstab

我在亚马逊红移中有一张表,我想沿着一列旋转。 E.g。

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不支持pivot,交叉表,unfst或案例扩展。此外,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 个答案:

答案 0 :(得分:0)

事实证明,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中有一个任意数量的值,这仍然很麻烦。我愿意接受更好的答案。