这种设计模式有时称为实体属性值 (EAV)。您可以动态创建所需的查询,尽管这有点费力。我不确定有没有办法返回匿名表类型,所以我不得不创建一个函数来创建一个函数:
Create or replace function generatecrosstab() returns void as $BODY$
Declare
sql varchar := '';
type varchar := '(assetid int, ';
sep varchar := '';
tagid int;
tname varchar(50);
Begin
for tagid, tname in select id, tagname from tag order by id
loop
sql := sql || sep || 'max(case tagid when '
|| tagid::varchar || ' then tagvalue end) ' || tname;
type := type || sep || tname || ' varchar(255)';
sep := ', ';
end loop;
type := type || ')';
sql = 'create or replace function crosstab() returns table '
|| type || ' as $$'
|| ' select assetid, ' || sql
|| ' from assettag group by assetid order by assetid;'
|| ' $$ Language sql;';
execute sql;
End;
$BODY$ Language plpgsql;
如果您执行此功能,例如:
select generatecrosstab();
它将创建一个函数 crosstab() ,您可以从中选择:
Select * From crosstab();
tablefunc 模块有一些可以简化事情的函数。
SQLFiddle Example