6

次の結果を配列にキャストする方法はありますか?

select pg_tables from pg_tables

これは1つの列のみを返しますが、データ型は配列ではありません。

編集:私はPostgreSql9.1.4を使用しています

更新:すべてのテーブルに適用可能な、列名を記述する必要のない、次のSQLステートメントと同等のものが必要です。

select 
    string_to_array(
    schemaname || '|' ||
    tablename || '|' || 
    tableowner || '|' ||
    coalesce(tablespace,'') || '|' ||
    hasindexes || '|' ||
    hasrules || '|' ||
    hastriggers
    ,'|')
from 
    pg_tables
4

4 に答える 4

9

これかもしれません:http ://www.sqlfiddle.com/#!1 / d41d8 / 364

select translate(string_to_array(x.*::text,',')::text,'()','')::text[] 
from pg_tables as x

それがどのように機能するか(裏返し)、5つのステップ:

1位:

select x.*::text from pg_tables as x;

サンプル出力:

|                                                            X |
----------------------------------------------------------------
|                    (pg_catalog,pg_statistic,postgres,,t,f,f) |
|                         (pg_catalog,pg_type,postgres,,t,f,f) |

2番目:

select string_to_array(x.*::text,',') from pg_tables as x;

サンプル出力:

|                           STRING_TO_ARRAY |
---------------------------------------------
| (pg_catalog,pg_statistic,postgres,,t,f,f) |
|      (pg_catalog,pg_type,postgres,,t,f,f) |

3位:

select string_to_array(x.*::text,',')::text from pg_tables as x;

サンプル出力:

|                               STRING_TO_ARRAY |
-------------------------------------------------
| {(pg_catalog,pg_statistic,postgres,"",t,f,f)} |
|      {(pg_catalog,pg_type,postgres,"",t,f,f)} |

4位:

select translate( string_to_array(x.*::text,',')::text, '()', '') from pg_tables as x

サンプル出力:

|                                   TRANSLATE |
-----------------------------------------------
| {pg_catalog,pg_statistic,postgres,"",t,f,f} |
|      {pg_catalog,pg_type,postgres,"",t,f,f} |

ついに:

select translate( string_to_array(x.*::text,',')::text, '()', '')::text[] 
from pg_tables as x

サンプル出力:

|                               TRANSLATE |
-------------------------------------------
| pg_catalog,pg_statistic,postgres,,t,f,f |
|      pg_catalog,pg_type,postgres,,t,f,f |

ライブテスト:http ://www.sqlfiddle.com/#!1 / d41d8 / 373

それが機能することを証明するには:

with a as 
(
  select translate( string_to_array(x.*::text,',')::text, '()', '')::text[] as colArray 
  from pg_tables as x
)
select row_number() over(), unnest(colArray)
from a;

サンプル出力:

| ROW_NUMBER |                  UNNEST |
----------------------------------------
|          1 |              pg_catalog |
|          1 |            pg_statistic |
|          1 |                postgres |
|          1 |                         |
|          1 |                       t |
|          1 |                       f |
|          1 |                       f |
|          2 |              pg_catalog |
|          2 |                 pg_type |
|          2 |                postgres |
|          2 |                         |
|          2 |                       t |
|          2 |                       f |
|          2 |                       f |
于 2012-07-13T11:48:41.087 に答える
6

別のアプローチ、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でテストできます

于 2012-07-13T14:44:20.270 に答える
2

NULLこの関数は、値、空の文字列、または値の特殊文字を含むすべてのコーナーケースで機能します。

CREATE OR REPLACE FUNCTION f_rows_to_arr(_tbl text)
  RETURNS SETOF text[] AS
$BODY$
BEGIN

RETURN QUERY EXECUTE '
SELECT ARRAY[' || (
        SELECT string_agg(quote_ident(attname) || '::text', ',')
        FROM   pg_catalog.pg_attribute 
        WHERE  attrelid = _tbl::regclass  -- valid, visible table name 
        AND    attnum > 0                 -- exclude tableoid & friends
        AND    attisdropped = FALSE       -- exclude dropped columns
        ) || ' ]
FROM   ' || _tbl::regclass;

END;
$BODY$ LANGUAGE plpgsql;

電話:

SELECT * FROM f_rows_to_arr ('mytbl');

regclassSQLiを回避するためのキャスト。このバージョンでは、列はソートされていません。この関連する回答の使用されたテクニックとリンクの詳細な説明。

于 2012-07-13T18:22:36.330 に答える
0

string_to_arrayが役立つ場合があります:

SELECT string_to_array(pg_tables::text,','::text) FROM pg_tables;
于 2012-07-13T11:04:42.920 に答える