在postgresql中将多列表转换为键名称值元组表

时间:2011-11-25 09:53:43

标签: database postgresql

我有大量的查询,其中一些可能需要半个小时才能运行,其中许多查询返回超过20个左右的列(是的,它们是标准化的)。我感兴趣的是将所有这些数据存储在一个表中,格式为Timestamp,name,value,这是为了以后对数据的自动化。

但是当我有一个返回

的查询时
T1, V1t1, V2t1, V3t1
T2, V1t2, v2t2, v3t2
--   --    --    --

我希望格式化数据

T1, Name(V1), V1t1
T1, Name(V2), V2t1
T1, Name(V3), V3t1
T2, Name(V1), V1t2
T2, Name(V2), V2t2
T2, Name(V3), V3t2

我知道我可以通过为每个值v1,v2和v3选择联合来做到这一点,

然而,我对速度很感兴趣,并希望避免发出3个查询,我可以将数据(尽管是wroung格式)放在一个......或者在实际情况下,不要发出20-30个查询,它可以可以一个人完成。

所以问题是,除了转储到临时表并将后续选择运行到表的相关列并将它们组合在一起之外,有没有办法做到这一点。

使用自定义构建的postgresql函数可以实现吗?

提前致谢

2 个答案:

答案 0 :(得分:2)

使用自定义PostgreSQL函数完全可行。您也可以使用tablefunc模块并使用crosstab function来执行您想要的操作。看起来你正试图在PostgreSQL中完成一个univot,所以你可以从这个邮件列表线程中获得更多的使用Unpivot with PostgreSQL

答案 1 :(得分:2)

您可以使用以下查询的变体来实现您想要的效果。

CREATE TABLE data
(
   sampleTime timestamptz,
   value1 numeric,
   value2 numeric,
   value3 numeric
);

INSERT INTO data(sampleTime,value1,value2,value3) values(now(),1,2,3);
INSERT INTO data(sampleTime,value1,value2,value3) values(now(),4,5,6);

SELECT data.sampleTime,
   CASE
      WHEN generate_series = 1 THEN 'value1'
      WHEN generate_series = 2 THEN 'value2'
      ELSE 'value3'
   END AS key,
   CASE
      WHEN generate_series = 1 THEN value1
      WHEN generate_series = 2 then value2
      ELSE value3 
   END AS value
FROM data,generate_series(1,3)
ORDER BY data.sampleTime,generate_series