Обсуждение: function to return rows as columns?

Поиск
Список
Период
Сортировка

function to return rows as columns?

От
Linos
Дата:
Hello,
    i have a query that returns a result set like this:

item | size | stock
123  | XL   | 10
123  | XXL | 5
123  | XS   | 3

and i would like get the results like this:

item | XL | XXL | XS
123  | 10  | 5     | 3

i have been thinking how to do it with a plpgsql function but the number of
sizes depend on the item that it is queried so i can not create a type and
return it, i could create it like a text concatenating the stock and size of
every row and returning the complete line text but i would have to process it in
the application anyway so i am searching a solution that lets me return it like
a record.

I have been searching the list and maybe i could create the record type inside
the function and to get the correct names and number of columns in the
application side launching a query to get the number of sizes before call the
function to specify the columns in the function call but maybe i am missing
anything important here? any better (or more correct) way to do this? Thanks.

Regards,
Miguel Angel.

Re: function to return rows as columns?

От
Thomas Kellerer
Дата:
Linos, 27.02.2009 11:41:
> Hello,
>     i have a query that returns a result set like this:
>
> item | size | stock
> 123  | XL   | 10
> 123  | XXL | 5
> 123  | XS   | 3
>
> and i would like get the results like this:
>
> item | XL | XXL | XS
> 123  | 10  | 5     | 3
>
> i have been thinking how to do it with a plpgsql function but the number
> of sizes depend on the item that it is queried so i can not create a
> type and return it, i could create it like a text concatenating the
> stock and size of every row and returning the complete line text but i
> would have to process it in the application anyway so i am searching a
> solution that lets me return it like a record.
>
> I have been searching the list and maybe i could create the record type
> inside the function and to get the correct names and number of columns
> in the application side launching a query to get the number of sizes
> before call the function to specify the columns in the function call but
> maybe i am missing anything important here? any better (or more correct)
> way to do this? Thanks.

Check out the "crosstab" function in the "Tablefunc" module:

http://www.postgresql.org/docs/current/static/tablefunc.html



Re: function to return rows as columns?

От
Linos
Дата:
Thomas Kellerer escribió:
> Linos, 27.02.2009 11:41:
>> Hello,
>>     i have a query that returns a result set like this:
>>
>> item | size | stock
>> 123  | XL   | 10
>> 123  | XXL | 5
>> 123  | XS   | 3
>>
>> and i would like get the results like this:
>>
>> item | XL | XXL | XS
>> 123  | 10  | 5     | 3
>>
>> i have been thinking how to do it with a plpgsql function but the
>> number of sizes depend on the item that it is queried so i can not
>> create a type and return it, i could create it like a text
>> concatenating the stock and size of every row and returning the
>> complete line text but i would have to process it in the application
>> anyway so i am searching a solution that lets me return it like a record.
>>
>> I have been searching the list and maybe i could create the record
>> type inside the function and to get the correct names and number of
>> columns in the application side launching a query to get the number of
>> sizes before call the function to specify the columns in the function
>> call but maybe i am missing anything important here? any better (or
>> more correct) way to do this? Thanks.
>
> Check out the "crosstab" function in the "Tablefunc" module:
>
> http://www.postgresql.org/docs/current/static/tablefunc.html
>
>

I knew i was missing something hehehe, thanks Thomas.



Re: function to return rows as columns?

От
"A. Kretschmer"
Дата:
In response to Linos :
> Hello,
>     i have a query that returns a result set like this:
>
> item | size | stock
> 123  | XL   | 10
> 123  | XXL | 5
> 123  | XS   | 3
>
> and i would like get the results like this:
>
> item | XL | XXL | XS
> 123  | 10  | 5     | 3

Other solution with plain SQL:

test=*# select * from linos ;
 item | size | stock
------+------+-------
  123 | XL   |    10
  123 | XXL  |     5
  123 | XS   |     3
(3 rows)

test=*# select item, sum(case when size='XL' then stock else 0 end) as
"XL", sum(case when size='XXL' then stock else 0 end) as "XXL", sum(case
when size='XS' then stock else 0 end) as "XS" from linos where item=123
group by item;
 item | XL | XXL | XS
------+----+-----+----
  123 | 10 |   5 |  3
(1 row)


Andreas
--
Andreas Kretschmer
Kontakt:  Heynitz: 035242/47150,   D1: 0160/7141639 (mehr: -> Header)
GnuPG-ID:   0x3FFF606C, privat 0x7F4584DA   http://wwwkeys.de.pgp.net

Re: function to return rows as columns?

От
Linos
Дата:
A. Kretschmer escribió:
> In response to Linos :
>> Hello,
>>     i have a query that returns a result set like this:
>>
>> item | size | stock
>> 123  | XL   | 10
>> 123  | XXL | 5
>> 123  | XS   | 3
>>
>> and i would like get the results like this:
>>
>> item | XL | XXL | XS
>> 123  | 10  | 5     | 3
>
> Other solution with plain SQL:
>
> test=*# select * from linos ;
>  item | size | stock
> ------+------+-------
>   123 | XL   |    10
>   123 | XXL  |     5
>   123 | XS   |     3
> (3 rows)
>
> test=*# select item, sum(case when size='XL' then stock else 0 end) as
> "XL", sum(case when size='XXL' then stock else 0 end) as "XXL", sum(case
> when size='XS' then stock else 0 end) as "XS" from linos where item=123
> group by item;
>  item | XL | XXL | XS
> ------+----+-----+----
>   123 | 10 |   5 |  3
> (1 row)
>
>
> Andreas

I think this approach have a problem (almost with my data), i have a somewhat
large number of different sizes, about 200 or so (although i have a presented a
limited example i now). Thanks anyway by the alternative way to do it Andreas.

Regards,
Miguel Angel.

Re: function to return rows as columns?

От
Sim Zacks
Дата:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

> I think this approach have a problem (almost with my data), i have a
> somewhat large number of different sizes, about 200 or so (although i
> have a presented a limited example i now). Thanks anyway by the
> alternative way to do it Andreas.
>
Actually the crosstab function won't work for you if you need something
more then the basic one or two columns. (IIRC).
Building a dynamic sql string such as Andreas suggested will always give
you exactly what you want.

Sim
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkmqp+wACgkQjDX6szCBa+r2IgCgpEGq1obqHtWcbbbdchm2cT1e
ShEAniOg/qut+DXQS2mwvSvAMtiE7eOi
=wKIf
-----END PGP SIGNATURE-----