【问题标题】:Multiple distinct arrays with null values among them多个不同的数组,其中包含空值
【发布时间】:2018-05-14 05:31:15
【问题描述】:

我有一个包含三个一维数组的表(还有一个主键和其他几列,但它们无关紧要)。所有这些数组都可以是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,等等,但都无济于事。

【问题讨论】:

    标签: sql postgresql postgresql-9.6


    【解决方案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) 
    

    【讨论】:

      【解决方案2】:

      如果我理解正确,您想要所有不同的值,但为 null?那么你就可以removeNULLs。绝对看起来不整洁,但是:

      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)
      

      对于 pre10 版本:

      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)
      

      【讨论】:

      • 真的如您所描述的那样对您有用吗?对我来说,它没有。见小提琴:sqlfiddle.com/#!17/875ea/1 我得到:"{text1,text2,text5}";"{1,2,3,5}";"{21,22,25}" - 这是同样的问题。包含数组的 NULL INSTEAD 的行中的值将被忽略。数组中的 NULL 值无关紧要。我认为你试图挽救后一种现象。
      • @cis 坦率地说我很惊讶内部连接在我的第一个示例中起作用:) 同时 sqlfiddle.com/#!17/875ea/4 起作用
      猜你喜欢
      • 1970-01-01
      • 2014-11-18
      • 2020-07-30
      • 2019-12-15
      • 1970-01-01
      • 2021-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多