[pgsql-jp: 41061] Re: 再起的なSQLで配列の型について
花田 茂
hanada @ metrosystems.co.jp
2012年 3月 1日 (木) 15:50:46 JST
花田です。
(2012/03/01 13:41), apostleofwhom wrote:
> id が text 型や varchar だとエラーにならないのですが、
> id を varchar(12) や varchar(64) にすると、
>
> ERROR: recursive query "rec" column 4 has type character varying(12)[]
> in non-recursive term but type character varying[] overall
> LINE 2: select t.id, t.parentid, 1, array[t.id]
>
> とエラーになります。SQL は以下となります。
エラーメッセージによると、UNION ALL の上下で path 列の型が精度情報のみ異
なっているので、エラーになっています。精度なしの varchar と varchar(12)
は、別の型という扱いです。|| 演算子で連結すると、精度情報が落ちてしまう
ようですね。
なお、文字列型の使い分けは Let's postgres にわかりやすい記事[1]がありま
すので、未読でしたらぜひ。
[1] http://lets.postgresql.jp/documents/technical/text-processing/1/
> with recursive rec(id, parentid, lv, path) as (
> select t.id, t.parentid, 1, array[t.id]
> from tree t
> where t.parentid is null
> union all
> select t.id, t.parentid, rec.lv + 1, rec.path || t.id
> from tree t, rec
> where t.parentid = rec.id
> )
> select id, parentid, lv, path
> from rec order by path;
>
> id を varchar(12) にしてもエラーにならないようにするには
> どうすればよろしいでしょうか。
path 列の型が varying[] 型でよければ、ARRAY[] や || を array_append() に
統一すれば OK のようです。
with recursive rec(id, parentid, lv, path) as (
select t.id, t.parentid, 1, array_append(NULL, t.id) path
from tree t
where t.parentid is null
union all
select t.id, t.parentid, rec.lv + 1, array_append(rec.path, t.id)
from tree t, rec
where t.parentid = rec.id
)
select id, parentid, lv, path
from rec order by path;
【結果】
id | parentid | lv | path
-----+----------+----+-------------------
001 | | 1 | {001}
002 | 001 | 2 | {001,002}
004 | 002 | 3 | {001,002,004}
005 | 002 | 3 | {001,002,005}
003 | 001 | 2 | {001,003}
006 | 003 | 3 | {001,003,006}
007 | 006 | 4 | {001,003,006,007}
008 | 006 | 4 | {001,003,006,008}
050 | | 1 | {050}
055 | 050 | 2 | {050,055}
056 | 050 | 2 | {050,056}
058 | 056 | 3 | {050,056,058}
(12 rows)
もし path 列の型を varying(12)[] にしたい場合は、
array_append(rec.path, t.id)::varchar(12)[]
のように array_append() の結果を UNION ALL の上下の両方キャストしてくだ
さい。
--
株式会社メトロシステムズ
花田 茂
Mail : hanada @ metrosystems.co.jp
Tel : 03-5951-1219
Fax : 03-5951-2929
pgsql-jp メーリングリストの案内