別のアプローチ、hstore
タイプを使用、これはより堅牢で、フィールドの値のコンマを解決できます
hstore
これを1回実行して、contribタイプを追加します。
CREATE EXTENSION hstore;
この関数を作成します。
create or replace function hstore_to_array(r hstore) returns text[] as
$$
begin
return array(select (each(r)).value);
end;
$$ language 'plpgsql';
次に、これを試してください:
select hstore_to_array(hstore(r)) from pg_tables r limit 10;
出力:
hstore_to_array
---------------------------------------------------
{f,pg_statistic,t,pg_catalog,postgres,NULL,f}
{f,pg_type,t,pg_catalog,postgres,NULL,f}
{f,pg_attribute,t,pg_catalog,postgres,NULL,f}
{f,xx,t,public,postgres,NULL,f}
{f,yy,t,public,postgres,NULL,f}
{f,tblx,f,public,postgres,NULL,f}
{f,pg_authid,t,pg_catalog,postgres,pg_global,f}
{f,pg_proc,t,pg_catalog,postgres,NULL,f}
{f,pg_class,t,pg_catalog,postgres,NULL,f}
{f,pg_database,t,pg_catalog,postgres,pg_global,f}
(10 rows)
もう一つの例:
create table Beatle(firstname text, middlename text, lastname text);
insert into Beatle(firstname, middlename, lastname) values
('John','Winston','Lennon'),
('Paul','','McCartney'),
('George',NULL,'Harrison'),
('Ringo','my passions are ring,drum and shades','Starr');
クエリ:
select hstore_to_array(hstore(b)) from Beatle b;
出力:
hstore_to_array
------------------------------------------------------
{Lennon,John,Winston}
{McCartney,Paul,""}
{Harrison,George,NULL}
{Starr,Ringo,"my passions are ring,drum and shades"}
(4 rows)
ご覧のとおり、カンマ付きの値でも適切に保持されます。
しかし、賢明な読者は上記の出力に何かに気付くでしょう。hstore関数は、フィールドの元の順序を保持しません。それを保持するために、テーブルをサブクエリに置きます。
select hstore_to_array(hstore(b)) from (select * from Beatle) as b
出力:
hstore_to_array
------------------------------------------------------
{John,Winston,Lennon}
{Paul,"",McCartney}
{George,NULL,Harrison}
{Ringo,"my passions are ring,drum and shades",Starr}
(4 rows)
使用された参照:http://okbob.blogspot.com/2009/10/dynamic-access-to-record-fields-in.html
次に注目する機能:http ://www.postgresonline.com/journal/archives/254-PostgreSQL-9.2-Preserving-column-names-of-subqueries.html
アップデート
サブクエリによる列の順序の保持は単なるまぐれのようです。並べ替えを試してみました(例:名)。
select hstore_to_array(hstore(b))
from (select * from Beatle order by firstname) as b
出力は、元の列の順序を保持しなくなります。
hstore_to_array
------------------------------------------------------
{Harrison,George,NULL}
{Lennon,John,Winston}
{McCartney,Paul,""}
{Starr,Ringo,"my passions are ring,drum and shades"}
(4 rows)
元の列の順序を保持する方法をさらに調査します。
アップデート
テーブルを並べ替える必要がある場合は、元の列の順序を保持するために、ORDER BY
サブクエリの外側を配置します。
select hstore_to_array(hstore(b))
from (select * from Beatle) as b order by firstname;
出力:
hstore_to_array
------------------------------------------------------
{George,NULL,Harrison}
{John,Winston,Lennon}
{Paul,"",McCartney}
{Ringo,"my passions are ring,drum and shades",Starr}
(4 rows)
今は正しいです。
また、メモリ内のテーブルから選択することもできます。
select hstore_to_array(hstore(b))
from
(
select * from
(values
('John',1940,'Winston','Lennon'),
('Paul',1942,'','McCartney'),
('George',1943,NULL,'Harrison'),
('Ringo',1940,'my passions are ring,drum and shades','Starr')
) as x(Firstname,BirthYear,Middlename,Lastname)
) as b
order by BirthYear desc, Firstname desc
出力:
hstore_to_array
-----------------------------------------------------------
{George,1943,NULL,Harrison}
{Paul,1942,"",McCartney}
{Ringo,1940,"my passions are ring,drum and shades",Starr}
{John,1940,Winston,Lennon}
(4 rows)
アップデート
hstore_to_array
機能はすでに組み込みの機能であることがわかりました。httpavals
: //www.postgresql.org/docs/9.1/static/hstore.htmlを使用してください。
select
avals (hstore(b))
from
(
select * from
(values
('John',1940,'Winston','Lennon'),
('Paul',1942,'','McCartney'),
('George',1943,NULL,'Harrison'),
('Ringo',1940,'my passions are ring,drum and shades','Starr')
) as x(Firstname,BirthYear,Middlename,Lastname)
) as b
order by BirthYear desc, Firstname desc;
出力:
avals
-----------------------------------------------------------
{George,1943,NULL,Harrison}
{Paul,1942,"",McCartney}
{Ringo,1940,"my passions are ring,drum and shades",Starr}
{John,1940,Winston,Lennon}
(4 rows)
別のサンプル:
select avals(hstore(b))
from (select * from Beatle) as b order by Firstname;
出力:
avals
------------------------------------------------------
{George,NULL,Harrison}
{John,Winston,Lennon}
{Paul,"",McCartney}
{Ringo,"my passions are ring,drum and shades",Starr}
(4 rows)
ツを使うだけavals
</p>
ライブテスト:http ://www.sqlfiddle.com/#!1 / d41d8 / 388
sqlfiddleの出力には配列インジケーター(中括弧)と「私の情熱はリング、ドラム、シェードです」の二重引用符はありませんが、avalsの結果は配列であり、コンマを含む文字列には二重引用符が含まれていることに注意してください。実際の結果は、pgAdminまたはpsqlでテストできます