我无法在此处发布原始查询,这太复杂了。所以我用一个示例查询来解释我的问题:
使用数据透视查询:
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)'
我想从查询中添加返回类型(粗体强调)。怎么做?
答案 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
。这两个语句必须在一个事务中执行。详细说明: