如何在Athena中转换数组中的SELECT sql查询结果

如何在Athena中转换数组中的SELECT sql查询结果,sql,amazon-athena,Sql,Amazon Athena,这是一个非常普遍的需要,可以帮助很多人。每当我们需要对信息进行分组并将分组后的值汇总为字符串时,它就会出现,如下所示: WITH example_table AS (SELECT 'First' as person, '2020-01-01' as _date, 1 as _value UNION ALL SELECT 'First', '2020-01-02', 0 UNION ALL SELECT 'First', '2020-01-03', 1 UNION ALL SELEC

这是一个非常普遍的需要,可以帮助很多人。每当我们需要对信息进行分组并将分组后的值汇总为字符串时,它就会出现,如下所示:

WITH example_table AS
 (SELECT 'First' as person, '2020-01-01' as _date, 1 as _value UNION ALL
  SELECT 'First', '2020-01-02', 0 UNION ALL
  SELECT 'First', '2020-01-03', 1 UNION ALL
  SELECT 'Second', '2020-01-01', 1 UNION ALL
  SELECT 'Second', '2020-01-02', 0)
SELECT person, min(_date), reduce(array_agg(_value ORDER BY _date), '', (s, x) -> CAST(s as varchar) || CAST(x as varchar), s -> s)
FROM example_table
GROUP BY person
人 访问日期 参观 弗斯特 2020-01-01 1. 弗斯特 2020-01-02 0 弗斯特 2020-01-03 1. 弗斯特 2020-01-04 1. 弗斯特 2020-01-05 0 第二 2020-01-01 0 第二 2020-01-02 1. 第二 2020-01-03 1. 第二 2020-01-04 0 第二 2020-01-05 1.
在雅典娜中,您可以使用
array\u agg()。但不幸的是,它伴随着这一点:

聚合函数不支持ORDER BY,例如,不能在数组_agg(x)中使用它

我认为排序很重要

如果您知道每个组的最大值数,可以使用如下条件聚合:

select person, min(date),
       ( max(case when seqnum = 1 then value else '' end) ||
         max(case when seqnum = 2 then value else '' end) ||
         max(case when seqnum = 3 then value else '' end) ||
         max(case when seqnum = 4 then value else '' end) ||
         max(case when seqnum = 5 then value else '' end)
       ) as values_5
from (select t.*,
             row_number() over (partition by person order by date) as seqnum
      from t
     ) t
group by person;

在一般情况下,您可以使用reduce和array_agg的组合,如下所示:

WITH example_table AS
 (SELECT 'First' as person, '2020-01-01' as _date, 1 as _value UNION ALL
  SELECT 'First', '2020-01-02', 0 UNION ALL
  SELECT 'First', '2020-01-03', 1 UNION ALL
  SELECT 'Second', '2020-01-01', 1 UNION ALL
  SELECT 'Second', '2020-01-02', 0)
SELECT person, min(_date), reduce(array_agg(_value ORDER BY _date), '', (s, x) -> CAST(s as varchar) || CAST(x as varchar), s -> s)
FROM example_table
GROUP BY person
array\u agg(\u value ORDER BY{u date)
将创建
数组[1,0,1]
,例如,为
第一个
人创建。reduce部分连接上述数组中数字的varchar

对于varchar的特定输出,您还可以使用array_join,这使得它更短:

WITH example_table AS
 (SELECT 'First' as person, '2020-01-01' as _date, 1 as _value UNION ALL
  SELECT 'First', '2020-01-02', 0 UNION ALL
  SELECT 'First', '2020-01-03', 1 UNION ALL
  SELECT 'Second', '2020-01-01', 1 UNION ALL
  SELECT 'Second', '2020-01-02', 0)
SELECT person, min(_date), array_join(array_agg(_value ORDER BY _date),'')
FROM example_table
GROUP BY person

顺便说一句,尽量避免在列名中使用诸如value或date之类的通用名称。你很可能会在一种或另一种语言中碰到一些保留字,很难理解你逻辑的含义。

回答得很好。非常感谢你。我认为你的解决方案解决了大多数情况。在我的示例中,它可能没有一般性,因为我不知道每个序列将有多少个元素,而且顺序对序列的影响很大。有没有一种方法可以构建一个函数,雅典娜这样称呼它:谢谢你的回复,它在这里帮助很大。还感谢您提供的问题格式提示。你能给我建议一个编辑这个问题的理想方法吗?我冒昧地编辑了你问题中的列名。