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

时间:2014-06-13 15:40:46

标签: sql postgresql

使用查询以及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中的空字符串,但不是很确定。

1 个答案:

答案 0 :(得分: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 <> ''会删除空蜇('')和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.