使用从另一个数组派生的项创建一个新数组

时间:2017-02-23 04:07:48

标签: arrays postgresql type-conversion

给定一种类型的PostgreSQL ARRAY项,如何创建一个新数组,其中每个项都是从初始数组中的项派生的?

示例:我有一组INTERVAL值。我想要一个新数组,其中每个项目都是NUMERIC(10, 1),这是相应INTERVAL值中的总秒数。

我知道如何转换一个INTERVAL值:

foo=> SELECT '00:01:20.000'::INTERVAL AS duration_interval;
 duration_interval 
-------------------
 00:01:20
(1 row)

foo=> SELECT extract(EPOCH FROM date_trunc('second', '00:01:20.000'::INTERVAL))
    ::NUMERIC(10, 1) AS duration_seconds;
 duration_seconds 
------------------
             80.0
(1 row)

表中不存在数组 - 这是从另一个函数调用返回的值 - 因此转换代码需要作为数组对其进行操作。

如何INTERVAL值的数组转换为相应NUMERIC值的数组?

1 个答案:

答案 0 :(得分:1)

您需要unnest()数组,进行转换,然后汇总回数组。

假设您想在具有主键的真实表上执行此操作:

SELECT pk, array_agg(extract(epoch from dur_int)::numeric(10,1)
                     ORDER BY ordinality) AS duration_seconds
FROM my_table, unnest(duration_interval) WITH ORDINALITY d(dur_int)
GROUP BY pk;

如果您有一个数组,例如函数调用的结果:

SELECT array_agg(extract(epoch from dur_int)::numeric(10,1)
                 ORDER BY ordinality) AS duration_seconds
FROM unnest(function(...)) WITH ORDINALITY d(dur_int);

请注意,在取消数组时需要WITH ORDINALITY clause。这会在结果中添加一列ordinality,以便每行都有两列:(dur_int interval, ordinality bigint)。当putting the array back again使用秒而不是间隔时,您可以按ordinality列对行进行排序。这样,您可以确保生成的秒数组中的顺序与原始数组间隔中的顺序相同。 (通常,SQL行源没有特定的顺序,服务器可能以它喜欢的任何顺序显示行。)

如果您可以访问该功能并且没有打破其他用途,那么通过更改功能可以更好地使用它,以便您可以直接使用它的结果。