昨日は「複数行の1次元配列」⇔ 2次元配列のクエリでした。今日は少し違って「一つの1次元配列」を2次元配列に組み換えるもの。行・列サイズ(縦・横の要素数)を任意に指定できるようにしました。PostgreSQL9.5で強化されたarray_agg関数を使うので、それ以前のバージョンでは動きません。動作確認したのは9.5.2。


イメージ的に似てるのは ↓Rmatrix関数。ベクトル(1次元配列)と行(または列)サイズを渡すと自動的に行列ができます。PostgreSQLでは行列を直接表す型がないので、2次元配列で代用してクエリで真似する感じ。
R version 3.2.4 Revised (2016-03-16 r70336) -- "Very Secure Dishes"
Copyright (C) 2016 The R Foundation for Statistical Computing
Platform: x86_64-unknown-cygwin (64-bit)
...

> matrix(1:100, nrow=10)
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    1   11   21   31   41   51   61   71   81    91
 [2,]    2   12   22   32   42   52   62   72   82    92
 [3,]    3   13   23   33   43   53   63   73   83    93
 [4,]    4   14   24   34   44   54   64   74   84    94
 [5,]    5   15   25   35   45   55   65   75   85    95
 [6,]    6   16   26   36   46   56   66   76   86    96
 [7,]    7   17   27   37   47   57   67   77   87    97
 [8,]    8   18   28   38   48   58   68   78   88    98
 [9,]    9   19   29   39   49   59   69   79   89    99
[10,]   10   20   30   40   50   60   70   80   90   100


簡単な例で、テキスト1文字ずつ1要素のこんな ↓1次元配列を元にします。
select '{あ,る,晴,れ,た,昼,下,が,り,市,場,へ,続,く,道,土,間,土,間,土,~,間}'
    :: text[]; 
+---------------------------------------------------------------------+
|                                text                                 |
+---------------------------------------------------------------------+
| {あ,る,晴,れ,た,昼,下,が,り,市,場,へ,続,く,道,土,間,土,間,土,~,間} |
+---------------------------------------------------------------------+
(1 row)


まず、指定した行サイズごとに別々の1次元配列にします。クエリは ↓ こんな感じ。配列型から任意の範囲を要素添字で取り出す書式を使用(array[:]、赤字の部分)。行×列の成分数から余った要素は無視されます。
with a (nrow, ncol, ary) as (
    select 5, 4, -- 任意の行・列サイズ
        '{あ,る,晴,れ,た,昼,下,が,り,市,場,へ,続,く,道,土,間,土,間,土,~,間}'
            :: text[]
)
select i, ary[low : low + ncol - 1]
from a, generate_series(1, nrow) as i, 
    cast((i - 1) * ncol + 1 as int) as low;
+---+---------------+
| i |      ary      |
+---+---------------+
| 1 | {あ,る,晴,れ} |
| 2 | {た,昼,下,が} |
| 3 | {り,市,場,へ} |
| 4 | {続,く,道,土} |
| 5 | {間,土,間,土} |
+---+---------------+
(5 rows)


後はarray_agg関数で束ねる ↓ だけ。これでarray[][]で値を取り出せる2次元配列になりました。繰り返しですがPostgreSQL9.5より前ではarray_aggに配列を渡せないので、使えません。
with a (nrow, ncol, ary) as (
    select 5, 4, 
        '{あ,る,晴,れ,た,昼,下,が,り,市,場,へ,続,く,道,土,間,土,間,土,~,間}'
            :: text[]
)
select array_agg(ary[low : low + ncol - 1])
from a, generate_series(1, nrow) as i, 
    cast((i - 1) * ncol + 1 as int) as low;
+-------------------------------------------------------------------------+
|                                array_agg                                |
+-------------------------------------------------------------------------+
| {{あ,る,晴,れ},{た,昼,下,が},{り,市,場,へ},{続,く,道,土},{間,土,間,土}} |
+-------------------------------------------------------------------------+
(1 row)


1次元配列の要素数が成分数(行×列)より少ないとエラーになります。最後の方で要素が少ない配列ができるため。それも許容して合体するジャグ配列はPostgreSQLの配列型は未対応。エラー処理を入れるなら、成分数に等しくなるまでNULL等の要素で詰めるとか。今回はそこまでしませんでした。
with a (nrow, ncol, ary) as (
    select 5, 4, 
        '{あ,る,晴,れ,た,昼,下,が,り,市,場,へ,続,く,道}'
            :: text[]
)
select array_agg(ary[low : low + ncol - 1])
from a, generate_series(1, nrow) as i, 
    cast((i - 1) * ncol + 1 as int) as low;
ERROR:  cannot accumulate arrays of different dimensionality


最後に、1次元配列の後ろから2次元配列にする例。WITH句で1ブロック挿入し配列を反転させます。他はこれまでと同一のクエリ。
with a (nrow, ncol, ary) as (
    select 5, 4, 
        '{あ,る,晴,れ,た,昼,下,が,り,市,場,へ,続,く,道,土,間,土,間,土,~,間}'
            :: text[]
), b (ary_rev) as (
    select array_agg(val order by o desc) -- 反転した配列
    from a, unnest(ary) with ordinality as x(val, o)
)
select array_agg(ary_rev[low : low + ncol - 1] )
from a, b, generate_series(1, nrow) as i, 
    cast((i - 1) * ncol + 1 as int) as low;
+-------------------------------------------------------------------------+
|                                array_agg                                |
+-------------------------------------------------------------------------+
| {{間,~,土,間},{土,間,土,道},{く,続,へ,場},{市,り,が,下},{昼,た,れ,晴}} |
+-------------------------------------------------------------------------+
(1 row)


ところでJSONB型にはjsonb_prettyという整形出力用の関数があり(9.5で追加)、長いデータも改行やスペース入りで表示され便利。配列型、とくに2次元以上のに同様な関数があったらいいなぁ。とりあえずストアドで何か考えます。