我有一个包含三个一维数组的表(还有一个主键和其他几个列,但它们并不重要)。所有这些数组都可以是NULL
。这些数组在每列中经常重叠:许多值都在几个数组中。我现在想要一个返回一行的查询,其中三个数组是整个数组列的不同值。
像这样创建测试表
DROP TABLE IF EXISTS my_array_test;
CREATE TABLE IF NOT EXISTS my_array_test(id integer, my_txt text[], my_int1 integer[], my_int2 integer[]);
INSERT INTO my_array_test(id, my_txt, my_int1, my_int2) VALUES (1,'{text1,text2}','{1,2}','{21,22}');
INSERT INTO my_array_test(id, my_txt, my_int1, my_int2) VALUES (2,null,'{7,8}','{21,22}');
INSERT INTO my_array_test(id, my_txt, my_int1, my_int2) VALUES (3,'{text2,text4}',null,null);
INSERT INTO my_array_test(id, my_txt, my_int1, my_int2) VALUES (3,null,null,'{17,18}');
INSERT INTO my_array_test(id, my_txt, my_int1, my_int2) VALUES (4,'{text1,text2}','{1,2,3}','{21,22}');
INSERT INTO my_array_test(id, my_txt, my_int1, my_int2) VALUES (5,'{text1,text5}','{1,5}','{21,25}');
INSERT INTO my_array_test(id, my_txt, my_int1, my_int2) VALUES (6,null,null,null);
结果类似于
select * from my_array_test ;
id | my_txt | my_int1 | my_int2
----+---------------+---------+---------
1 | {text1,text2} | {1,2} | {21,22}
2 | | {7,8} | {21,22}
3 | {text2,text4} | |
3 | | | {17,18}
4 | {text1,text2} | {1,2,3} | {21,22}
5 | {text1,text5} | {1,5} | {21,25}
6 | | |
(7 rows)
预期结果为{text1,text2,text4,text5},{1,2,7,8,2,5},{21,22,17,18,25}
(数组中的顺序并不重要。)
我尝试的是一个多边横向查询,如下所示:
SELECT
array_agg(DISTINCT t) AS text_array_result,
array_agg(DISTINCT i1) AS integer_array1_result,
array_agg(DISTINCT i2) AS integer_array2_result
FROM
my_array_test,
unnest(my_txt) AS t,
unnest(my_int1) AS i1,
unnest(my_int2) AS i2
但是,它会杀死所有仅包含NULL
个数组的行的值。
我也试过unnest(COALESCE(my_txt,'{}')) AS t,
等等,但无济于事。
答案 0 :(得分:1)
如果我理解你,你想要所有不同的值,但是null?然后你就可以remove NULL
了。 definetely看起来并不整洁,但是:
t=# with u as (select unnest(my_txt) a,unnest(my_int1) b,unnest(my_int2) v from my_array_test)
select array_remove(array_agg(distinct a),NULL),array_remove(array_agg(distinct b),NULL),array_remove(array_agg(distinct v),NULL) from u;
array_remove | array_remove | array_remove
---------------------------+---------------+------------------
{text1,text2,text4,text5} | {1,2,3,5,7,8} | {17,18,21,22,25}
(1 row)
for pre10 version:
t=# SELECT
array_remove(array_agg(DISTINCT t),NULL) AS text_array_result,
array_remove(array_agg(DISTINCT i1),NULL) AS integer_array1_result,
array_remove(array_agg(DISTINCT i2),NULL) AS integer_array2_result
FROM
my_array_test
left outer join unnest(my_txt) AS t on true
left outer join unnest(my_int1) AS i1 on true
left outer join unnest(my_int2) AS i2 on true
;
text_array_result | integer_array1_result | integer_array2_result
---------------------------+-----------------------+-----------------------
{text1,text2,text4,text5} | {1,2,3,5,7,8} | {17,18,21,22,25}
(1 row)
答案 1 :(得分:1)
您可以使用我所描述的自定义聚合in this post.
select
array_merge_agg(my_txt) AS text_array_result,
array_merge_agg(my_int1) AS integer_array1_result,
array_merge_agg(my_int2) AS integer_array2_result
from
my_array_test;
text_array_result | integer_array1_result | integer_array2_result
---------------------------+-----------------------+-----------------------
{text1,text2,text4,text5} | {1,2,3,5,7,8} | {17,18,21,22,25}
(1 row)