Postgres:将元素数组转换为多行

Posted

技术标签:

【中文标题】Postgres:将元素数组转换为多行【英文标题】:Postgres: convert array of elements to multiple rows 【发布时间】:2014-06-13 15:40:45 【问题描述】:

使用查询以及 postgres 中可用的函数(例如 string_to_arraystring_agg),将原始表中的数据转换为以下结果集。

id, text
001, foo,boo,foo
002, "",for,test,friday
003, "","",test,friday,tuesday,foo,boo

这里的 id 是一个人的 id,而 text 实际上是数组的类型。现在我要做的是生成以下结构。

id, text, text_count
001, foo, 2
001, boo, 1
002, test, 1
002, friday, 1 

这是我用来获取我提到的现有格式的查询,但是如何增强此查询以获取 id、text、text_count 结果。

select id, string_to_array(string_agg(b.text,' '), ' ') as words
from tableA a,tableB b group by id

我也想用 "" 去掉数据,我相信它们在 postgres 中是空字符串,但不太确定。

【问题讨论】:

您正在尝试按 id 和 text 分组?您的原始数据是什么样的? 【参考方案1】:

使用unnest()。 假设 id 是唯一的:

SELECT id, txt, count(*) As txt_count
FROM  (
   SELECT id
        , unnest(txt) AS txt
   FROM   tbl
   ) sub
WHERE  txt <> ''
GROUP  BY id, txt
ORDER  BY id, txt;

txt 而不是text,因为我从不使用基本类型名称作为标识符。 条件 WHERE txt &lt;&gt; '' 会删除空刺 ('') 以及 NULL 值。

取消嵌套数组时,结果集中的行数与数组中的元素数一样多。小心,并行取消嵌套多个数组时:Is there something like a zip() function in PostgreSQL that combines two arrays?Parallel unnest() and sort order in PostgreSQL

Postgres 9.3+ 中有一个更简洁的语法变体,带有 LATERAL JOIN:

SELECT id, txt, count(*) As txt_count
FROM  (
   SELECT id, x.txt
   FROM   tbl t, unnest(t.txt) x(txt)
   ) sub
WHERE  txt <> ''
GROUP  BY id, txt
ORDER  BY id, txt;

详情请看:PostgreSQL unnest() with element number

SQL Fiddle.

【讨论】:

我可以在值中使用我的查询吗,因为我的所有查询都会吐出这些值。 @Null-Hypothesis:我使用表格而不是 VALUES 表达式添加了一个更简洁的表格(这只是实际表格的快速替代品)。还有一把小提琴。 所以我不需要使用 string_to_array(string_agg(b.text,' '), ' ')?因为如果没有该查询,我就没有您提到的查询所需的数据。 @Null-Hypothesis:你写了text is actually type of array。如果它是我的 sqlfiddle 中的数组 (text[]),那么您只需要 unnest()。在问题中提供 表定义 总是更好...

以上是关于Postgres:将元素数组转换为多行的主要内容,如果未能解决你的问题,请参考以下文章

教义简单数组/数组转换为postgres int数组?

AWS Glue 将字符串值从 postgres 转换为 json 数组

postgres 行到二维数组

对于选择中的每个位置,将多行分组为一个字符串 postgres

Postgres 合并为空 JSONB 数组

使用 postgres 9.4 将 JSON 元素附加到数组