来自另一个查询的crosstab()查询的连接返回类型

时间:2014-08-22 14:24:11

标签: sql postgresql dynamic-sql crosstab postgresql-9.3

我无法在此处发布原始查询,这太复杂了。所以我用一个示例查询来解释我的问题:

使用数据透视查询:

Select pivot.* from public.crosstab($$ select 'na' as na, 1 as analysis,100 as value 
 union all select 'ba' as na, 2 as analysis,100 as value $$,
 $$ VALUES ('1'), ('2')$$
) as pivot (na text, "1" integer,"2" integer)

但我想像这样使用它:

Select pivot.* from public.crosstab($$ select 'na' as na, 1 as analysis,100 as value 
 union all select 'ba' as na, 2 as analysis,100 as value $$,
 $$ VALUES ('1'), ('2')$$
) as pivot select '(na text,"1" integer,"2" integer)'

我想从查询中添加返回类型(粗体强调)。怎么做?

1 个答案:

答案 0 :(得分:2)

清除测试用例

首先,我形成并澄清了你的例子:

SELECT * FROM public.crosstab(
   $$VALUES ('na', 1, 100)   -- VALUES expression does the same, shorter
          , ('ba', 2, 300)$$ -- no column names needed (ignored anyway)
  ,$$VALUES ('1'), ('2')$$
   ) AS pivot (na text, co11 int, col2 int)  -- sane column names

输入表:

col1  key  val
---------------
na    1    100
ba    2    300

输出表

na    co11    col2
--------------------
na    100     <NULL>
ba    <NULL>  300

您可以自由选择输出列名称,无需坚持使用"1""2"等笨拙的名称。只有数据类型必须匹配。

动态返回类型

您无法从查询中提供列定义列表。我们在这里有很多类似的要求。它们都与SQL的性质相冲突,SQL不接受“事后”的返回类型。必须使用查询声明,至少在执行时是这样。

您必须使用要在第二个示例中添加的crosstab()查询的输出构建SELECT查询。 两次往返服务器。

但是我们可以从系统目录中读取熟知的类型 - 毕竟这是SELECT * FROM tbl所做的。我努力并实施了我在相关答案中找到的内容:

我的功能crosstab_n()可能是你最好的选择。 阅读相关链接的答案!

它是crosstab()的包装器,它接受查询字符串(就像crosstab())和另一个提供返回类型的多态参数。我们仍然无法动态传递返回类型 。 SQL唯一可接受的方法是从系统目录中读取它。因此,我们通过创建临时表来“动态”安装复合类型:

CREATE TEMP TABLE my_pivot (na text, col1 int, col2 int);

SELECT * FROM crosstab_n(
    $$VALUES ('na', 1, 100), ('ba', 2, 100)$$
    ,NULL::my_pivot
    );

结果如上。瞧!

如果您希望临时表仅用于事务,请向其添加ON COMMIT DROP。这两个语句必须在一个事务中执行。详细说明: