PostgreSQL 9.3:动态交叉表标签查询

时间:2014-11-25 05:30:39

标签: postgresql pivot crosstab postgresql-9.3

我是PostgreSQL的新用户,版本是9.3。

我有下表和一些记录:

示例

create table tst
(
cola varchar(10),
colc varchar(10)
)

insert into tst values('101','A1');
insert into tst values('101','A2');
insert into tst values('201','A3');
insert into tst values('301','A4');
insert into tst values('401','A1');
insert into tst values('101','A6');
insert into tst values('201','A1');
insert into tst values('201','A5'); 

注意:现在我只想显示cola属于colc的值的记录。如果用户将colc值作为参数传递给函数,则必须匹配colc属于cola值的确切值。

预期结果

如果用户通过A1,A2,A6,则结果应为:

cola   A1   A2   A6
--------------------
101    1    1    1

注意:在上面的结果中,显示记录101,因为它属于A1,A2,A6而不属于其他值。 201未显示,因为它也属于A1,A3A5

如果用户通过A1,则结果应为:

cola   A1 
----------
401    1  

注意:在上面的结果中,显示记录401,因为它只属于A1

我没有得到如何在函数内为这个场景编写交叉表。

1 个答案:

答案 0 :(得分:1)

服务器端函数在PostgreSQL中不能有动态返回类型,因此无法从固定函数中获取所提到的结果。

此外,它看起来不像典型的交叉表问题。输出的cola部分可以通过过滤聚合获得,而其他列A1/A2/A6实际上是输入,因此在客户端的上下文中将它们作为列复制到输出中很容易 - 一边生成查询。

查找匹配行的实际SQL查询的要点是:

select cola from ts
group by cola
having array_agg(colc order by colc)='{A1,A2,A6}'

这会找到101

添加其他列只是一个客户端呈现问题。例如,查询可以这样写:

select cola, 1 as A1, 1 as A2, 1 as A6 from tst
group by cola
having array_agg(colc order by colc)='{A1,A2,A6}';

结果:

 cola | a1 | a2 | a6 
------+----+----+----
 101  |  1 |  1 |  1