Another approach, use the hstore
type, it is more reliable, can resolve the comma in the field value
Add the hstore
contrib type by doing this once:
CREATE EXTENSION hstore;
Create this function:
create or replace function hstore_to_array(r hstore) returns text[] as $$ begin return array(select (each(r)).value); end; $$ language 'plpgsql';
Then try the following:
select hstore_to_array(hstore(r)) from pg_tables r limit 10;
Conclusion:
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)
Another example:
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');
Query:
select hstore_to_array(hstore(b)) from Beatle b;
Conclusion:
hstore_to_array ------------------------------------------------------ {Lennon,John,Winston} {McCartney,Paul,""} {Harrison,George,NULL} {Starr,Ringo,"my passions are ring,drum and shades"} (4 rows)
As we can see, even a semicolon value is stored properly.
An astute reader will notice something on the above output. The hstore function does not provide the initial field order. To save it, put the table in a subquery, i.e.
select hstore_to_array(hstore(b)) from (select * from Beatle) as b
Conclusion:
hstore_to_array ------------------------------------------------------ {John,Winston,Lennon} {Paul,"",McCartney} {George,NULL,Harrison} {Ringo,"my passions are ring,drum and shades",Starr} (4 rows)
Used links: http://okbob.blogspot.com/2009/10/dynamic-access-to-record-fields-in.html
The following function to view: http://www.postgresonline.com/journal/archives/254-PostgreSQL-9.2-Preserving-column-names-of-subqueries.html
UPDATE
It seems that keeping column ordering through a subquery is just an accident. I tried to sort (for example, by first name).
select hstore_to_array(hstore(b)) from (select * from Beatle order by firstname) as b
The output does not preserve the order of the original columns:
hstore_to_array ------------------------------------------------------ {Harrison,George,NULL} {Lennon,John,Winston} {McCartney,Paul,""} {Starr,Ringo,"my passions are ring,drum and shades"} (4 rows)
Next, weβll explore how to preserve the original column order.
UPDATE
If you need to sort the table to preserve the original column order, put ORDER BY
outside the subquery:
select hstore_to_array(hstore(b)) from (select * from Beatle) as b order by firstname;
Conclusion:
hstore_to_array ------------------------------------------------------ {George,NULL,Harrison} {John,Winston,Lennon} {Paul,"",McCartney} {Ringo,"my passions are ring,drum and shades",Starr} (4 rows)
Now this is correct.
And choosing from a table in memory also works:
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
Conclusion:
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)
UPDATE
It turns out that the hstore_to_array
functionality already has built-in functionality, just use 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;
Conclusion:
avals ----------------------------------------------------------- {George,1943,NULL,Harrison} {Paul,1942,"",McCartney} {Ringo,1940,"my passions are ring,drum and shades",Starr} {John,1940,Winston,Lennon} (4 rows)
One more example:
select avals(hstore(b)) from (select * from Beatle) as b order by Firstname;
Conclusion:
avals ------------------------------------------------------ {George,NULL,Harrison} {John,Winston,Lennon} {Paul,"",McCartney} {Ringo,"my passions are ring,drum and shades",Starr} (4 rows)
Just use avals
γ
Live test : http://www.sqlfiddle.com/#!1/d41d8/388
Please note that although the sqlfiddle output does not have an array indicator (curly braces) and double quotes on , my passions are a ring, a drum and shades, "the result of avals is an array and the semicolon in them has a double quote in the actual results, you can check it on your pgAdmin or psql