Pad arrays with NULL to maximum length for custom aggregate function

后端 未结 1 1582
没有蜡笔的小新
没有蜡笔的小新 2021-01-15 01:18

From the answer of the question How to use array_agg() for varchar[],

We can create a custom aggregate function to aggregate n-dimensional arrays in Postgres like:

相关标签:
1条回答
  • 2021-01-15 01:33

    Using the custom aggregate function array_agg_mult() like defined in this related answer:

    • Selecting data into a Postgres array

    Your expected result is impossible:

    {{1},NULL,{abc}}

    Would have to be:

    {{1},{NULL},{abc}}
    

    Simple case with 0 or 1 array elements

    For the simple case to just replace the empty array: You can achieve that with:

    WITH t(arr) AS (
        VALUES
          ('{1}'::text[])
         ,('{}')
         ,('{abc}')
       )
    SELECT array_agg_mult(ARRAY[CASE WHEN arr = '{}' THEN '{NULL}' ELSE arr END])
    FROM   t;
    

    Dynamic padding for n elements

    Using array_fill() to pad arrays with NULL elements up to the maximum length:

    SELECT array_agg_mult(ARRAY[
             arr || array_fill(NULL::text
                             , ARRAY[max_elem - COALESCE(array_length(arr, 1), 0)])
           ]) AS result
    FROM   t, (SELECT max(array_length(arr, 1)) AS max_elem FROM t) t1;
    

    Still only works for 1-dimensional basic arrays.

    Explain

    • Subquery t1 computes the maximum length of the basic 1-dimensional array.
    • COALESCE(array_length(arr, 1), 0) computes the length of the array in this row.
      COALESCE defaults to 0 for NULL.
    • Generate padding array for the difference in length with array_fill().
    • Append that to arr with ||
    • Aggregate like above with array_agg_mult().

    SQL Fiddle. demonstrating all.
    Output in SQL Fiddle is misleading, so I cast result to text there.

    0 讨论(0)
提交回复
热议问题