在Postgres中将列转换为行

时间:2014-02-21 09:14:17

标签: postgresql pivot crosstab

我的表名是osk,st,item。 osk字段为stid,stock,free,npr,itemno。 st字段为stid,name。项目字段为id,name。我有多个架构。每个模式都有这个表

select i.name,st.name,stock,freestock from osk,st,items i where i.id=osk.itemno 
and st.stid=osk.stid

此查询返回结果,如此

  Name   St.Name    Stock   FreeStock
   A        B         10        20
   D        B         10        10
   C        E         12        10

但我想要

 Name    B (stock)     B(Free)   E(Stock)  E (Free Stock)
  A        10           20         -           -
  D        10           10         -           -
  C        -            -          12          10

如何实现这一目标。 (我有多个架构。所有架构都有这个表我希望从所有架构中回溯)

正在使用 postgresql 9.3 。如果可以使用CrossTab?怎么用?

1 个答案:

答案 0 :(得分:0)

假设您有一个这样的表(由于您未提供确切的表定义,因此必须猜测):

create table some_table (
  name text,
  stname text,
  stock int,
  freestock int
 );

insert into some_table values
('A', 'B', 10, 20),
('D', 'B', 10, 10),
('C', 'E', 12, 10);

现在您可以使用此处记录的crosstab函数:http://www.postgresql.org/docs/current/static/tablefunc.html

create extension if not exists tablefunc;

select coalesce(stock.name, freestock.name) as name,
       stock.b as "B (stock)",
       freestock.b as "B (free)",
       stock.e as "E (stock)",
       freestock.e as "E (free)"
from 
    crosstab('
        select name,
            stname,
            stock
        from some_table
    ', '
        select distinct stname
        from some_table
        order by stname
    ') as stock(name text, b int, e int)
full outer join 
    crosstab('
        select name,
            stname,
            freestock
        from some_table
    ', '
        select distinct stname
        from some_table
        order by stname
    ') as freestock(name text, b int, e int)
on stock.name = freestock.name;

结果是:

 name | B (stock) | B (free) | E (stock) | E (free)
------+-----------+----------+-----------+----------
 A    |        10 |       20 |           |
 C    |           |          |        12 |       10
 D    |        10 |       10 |           |
(3 rows)