Postgresql - 将整行返回为数组

Tom*_*eif 6 sql postgresql

有没有办法如何将以下结果转换为数组?

select pg_tables from pg_tables
Run Code Online (Sandbox Code Playgroud)

这将仅返回一列,但数据类型不是数组.

编辑:我正在使用PostgreSql 9.1.4

更新:我需要等效的以下SQL语句,而不需要编写适用于每个表的列名:

select 
    string_to_array(
    schemaname || '|' ||
    tablename || '|' || 
    tableowner || '|' ||
    coalesce(tablespace,'') || '|' ||
    hasindexes || '|' ||
    hasrules || '|' ||
    hastriggers
    ,'|')
from 
    pg_tables
Run Code Online (Sandbox Code Playgroud)

Mic*_*uen 9

可能是这样的:http://www.sqlfiddle.com/#!1/d41d8/364

select translate(string_to_array(x.*::text,',')::text,'()','')::text[] 
from pg_tables as x
Run Code Online (Sandbox Code Playgroud)

工作原理(由内而外),5个步骤:

第一名:

select x.*::text from pg_tables as x;
Run Code Online (Sandbox Code Playgroud)

样本输出:

|                                                            X |
----------------------------------------------------------------
|                    (pg_catalog,pg_statistic,postgres,,t,f,f) |
|                         (pg_catalog,pg_type,postgres,,t,f,f) |
Run Code Online (Sandbox Code Playgroud)

第二:

select string_to_array(x.*::text,',') from pg_tables as x;
Run Code Online (Sandbox Code Playgroud)

样本输出:

|                           STRING_TO_ARRAY |
---------------------------------------------
| (pg_catalog,pg_statistic,postgres,,t,f,f) |
|      (pg_catalog,pg_type,postgres,,t,f,f) |
Run Code Online (Sandbox Code Playgroud)

第三:

select string_to_array(x.*::text,',')::text from pg_tables as x;
Run Code Online (Sandbox Code Playgroud)

样本输出:

|                               STRING_TO_ARRAY |
-------------------------------------------------
| {(pg_catalog,pg_statistic,postgres,"",t,f,f)} |
|      {(pg_catalog,pg_type,postgres,"",t,f,f)} |
Run Code Online (Sandbox Code Playgroud)

第4名:

select translate( string_to_array(x.*::text,',')::text, '()', '') from pg_tables as x
Run Code Online (Sandbox Code Playgroud)

样本输出:

|                                   TRANSLATE |
-----------------------------------------------
| {pg_catalog,pg_statistic,postgres,"",t,f,f} |
|      {pg_catalog,pg_type,postgres,"",t,f,f} |
Run Code Online (Sandbox Code Playgroud)

最后:

select translate( string_to_array(x.*::text,',')::text, '()', '')::text[] 
from pg_tables as x
Run Code Online (Sandbox Code Playgroud)

样本输出:

|                               TRANSLATE |
-------------------------------------------
| pg_catalog,pg_statistic,postgres,,t,f,f |
|      pg_catalog,pg_type,postgres,,t,f,f |
Run Code Online (Sandbox Code Playgroud)

现场测试: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;
Run Code Online (Sandbox Code Playgroud)

样本输出:

| 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 |
Run Code Online (Sandbox Code Playgroud)

  • 有一个sqlfiddle.凉! (3认同)

Mic*_*uen 6

另一种方法,使用hstore类型,这样更健壮,可以解决字段值中的逗号

hstore通过执行一次添加contrib类型:

CREATE EXTENSION hstore; 
Run Code Online (Sandbox Code Playgroud)

创建此功能:

create or replace function hstore_to_array(r hstore) returns text[] as
$$
begin
    return array(select (each(r)).value);
end;
$$ language 'plpgsql';
Run Code Online (Sandbox Code Playgroud)

然后尝试这个:

select hstore_to_array(hstore(r)) from pg_tables r limit 10;
Run Code Online (Sandbox Code Playgroud)

输出:

                  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)
Run Code Online (Sandbox Code Playgroud)

另一个例子:

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');
Run Code Online (Sandbox Code Playgroud)

查询:

select hstore_to_array(hstore(b)) from Beatle b;
Run Code Online (Sandbox Code Playgroud)

输出:

                   hstore_to_array                    
------------------------------------------------------
 {Lennon,John,Winston}
 {McCartney,Paul,""}
 {Harrison,George,NULL}
 {Starr,Ringo,"my passions are ring,drum and shades"}
(4 rows)
Run Code Online (Sandbox Code Playgroud)

我们可以看到,即使使用逗号的值也可以正确保存.

精明的读者会注意到上面的输出.hstore函数不会预先确定字段的原始顺序.为了保留它,将表放在子查询上,即

select hstore_to_array(hstore(b)) from (select * from Beatle) as b
Run Code Online (Sandbox Code Playgroud)

输出:

                   hstore_to_array                    
------------------------------------------------------
 {John,Winston,Lennon}
 {Paul,"",McCartney}
 {George,NULL,Harrison}
 {Ringo,"my passions are ring,drum and shades",Starr}
(4 rows)
Run Code Online (Sandbox Code Playgroud)

使用的参考文献: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


UPDATE

看起来通过子查询保留列排序只是一个侥幸.我尝试进行排序(例如,在名字上).

select hstore_to_array(hstore(b)) 
from (select * from Beatle order by firstname) as b
Run Code Online (Sandbox Code Playgroud)

输出不再保留原始列顺序:

                   hstore_to_array                    
------------------------------------------------------
 {Harrison,George,NULL}
 {Lennon,John,Winston}
 {McCartney,Paul,""}
 {Starr,Ringo,"my passions are ring,drum and shades"}
(4 rows)
Run Code Online (Sandbox Code Playgroud)

将进一步调查如何保留原始列顺序.


UPDATE

如果需要对表进行排序,为了保留原始列的顺序,请将ORDER BY子查询的外部:

select hstore_to_array(hstore(b)) 
from (select * from Beatle) as b order by firstname;
Run Code Online (Sandbox Code Playgroud)

输出:

                   hstore_to_array                    
------------------------------------------------------
 {George,NULL,Harrison}
 {John,Winston,Lennon}
 {Paul,"",McCartney}
 {Ringo,"my passions are ring,drum and shades",Starr}
(4 rows)
Run Code Online (Sandbox Code Playgroud)

现在这是正确的.

从内存表中选择也可以:

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
Run Code Online (Sandbox Code Playgroud)

输出:

                      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)
Run Code Online (Sandbox Code Playgroud)

UPDATE

事实证明hstore_to_array,功能已经是一种内置功能,只需使用avals:http://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;
Run Code Online (Sandbox Code Playgroud)

输出:

                           avals                           
-----------------------------------------------------------
 {George,1943,NULL,Harrison}
 {Paul,1942,"",McCartney}
 {Ringo,1940,"my passions are ring,drum and shades",Starr}
 {John,1940,Winston,Lennon}
(4 rows)
Run Code Online (Sandbox Code Playgroud)

另一个样本:

select avals(hstore(b)) 
from (select * from Beatle) as b order by Firstname;
Run Code Online (Sandbox Code Playgroud)

输出:

                        avals
------------------------------------------------------
 {George,NULL,Harrison}
 {John,Winston,Lennon}
 {Paul,"",McCartney}
 {Ringo,"my passions are ring,drum and shades",Starr}
(4 rows)
Run Code Online (Sandbox Code Playgroud)

只需使用avals

现场测试:http://www.sqlfiddle.com/#!1/d41d8/388

请注意,虽然sqlfiddle输出没有数组指示器(花括号)和双引号"我的激情是响铃,鼓和阴影",但avals结果是一个数组,其中带有逗号的字符串有双引号实际结果,你可以在你的pgAdmin或psql上测试它