如何在Postgres 9.5中将行转换为列?

时间:2016-05-19 15:03:31

标签: sql postgresql pivot

我在输入中有这个表,它总是只包含三行。

public class ClassE<T implements InterW> extends ClassZ {
}

我想要这个输出:

| data |  
--------
|   X  | 
|   Y  |
|   Z  |

我尝试使用| data1| data2 | data3 | -------+-------+-------+ | X | Y | Z | 函数,但据我所知,它需要更多信息,例如category列和row_name列。我没有它们。

可以转置此表吗?

2 个答案:

答案 0 :(得分:0)

您不需要交叉表函数来执行此操作,只使用简单的PIVOT查询:

SELECT max( case rn when 1 then data end ) as data1,
       max( case rn when 2 then data end ) as data2,
       max( case rn when 3 then data end ) as data3
FROM (
   SELECT *,
          row_number() over ( ORDER BY data ) rn
   FROM table1
) x

演示:http://sqlfiddle.com/#!15/bead8/4

您需要考虑此查询中的一个陷阱 根据定义,数据库表是一个无序的集合元组,几乎没有任何数据库保证行的排序,除非在查询表的SELECT语句中指定了ORDER BY子句。
因此,查询使用ORDER BY data子句以这种方式对行进行排序,X将放入data1列,Y放置到data2和{ {1}}到Z,按此顺序(因为X&lt; Y&lt; Z) 您需要更改此子句如果您需要使用其他一些订单(或者此表的某些其他列来确定此订单)。

答案 1 :(得分:0)

对于固定列/行计数:

select
  data[1] as data1,
  data[2] as data2,
  data[3] as data3
from
  (select array_agg(data) as data from t) as t;

对于可变列/行计数(只有一种来自多种可能性):

create function prepare_statement(in p_name text, in p_body text) returns void as $$
declare
  s text;
begin
  s := 'prepare ' || p_name || ' as ' || p_body;
  execute s;
  return;
end; $$ language plpgsql;

然后:

select prepare_statement('foo', (
  select 
    'select ' || 
    string_agg('data['||i||'] as data'||i, ', ') || 
    ' from (select array_agg(data) as data from t) as t'
  from generate_series(1, (select count(*) from t)) n(i))
  );

execute foo;

-- deallocate foo; -- to deallocate previously prepared statement

了解更多关于
的信息 arrays
array_agg function
prepare/execute/deallocate statements