0

我的交叉表查询(见下文)运行良好。但是,我必须生成大量这样的查询,而且 - 至关重要的是 - 列定义的数量每天都会有所不同。如果输出 columndef 的数量与交叉表的第二个参数的数量不匹配,则交叉表将抛出错误并中止。因此,我不能像在当前查询中那样“硬连线”列定义,而是需要一个函数来确保列定义将即时同步。是否可以编写一个在所有此类情况下都可重用的通用 postgres 函数?这是我的查询:

SELECT *
FROM crosstab
('SELECT 
to_char(ipstimestamp, ''mon DD HH24h'') As row_name, 
ips.objectid::text As category, 
COUNT(*)::integer As value
FROM loggingdb_ips_boolean As log 
INNER JOIN IpsObjects As ips 
ON log.Varid=ips.ObjectId
WHERE ((    log.varid = 37551) 
OR (log.varid = 27087)
OR (log.varid = 29469)   
OR (log.varid = 50876)
OR (log.varid = 45096)
OR (log.varid = 54708)
OR (log.varid = 47475)
OR (log.varid = 54606)
OR (log.varid = 25528)
OR (log.varid = 54729))
 GROUP BY to_char(ipstimestamp, ''yyyy MM DD HH24h''), row_name, objectid, category     
 ORDER BY to_char(ipstimestamp, ''yyyy MM DD HH24h''), row_name, objectid, category', 

 'SELECT DISTINCT varid 
 FROM loggingdb_ips_boolean ORDER BY 1;' 
 )

 As CountsPerHour(row_name text,  
 "25528" integer,
 "27087" integer,
 "29469" integer,
 "37551" integer,
 "45096" integer,
 "54606" integer,
 "54708" integer,
 "54729" integer)

PS:请注意,此查询可以针对以下服务器上的测试数据运行:主机:bellariastrasse.com 数据库:IpsLogging 用户:访客密码:访客

4

1 回答 1

2

恐怕你想要的不是完全可能的。如果返回类型不同,您可以

  • 创建一个返回泛型的函数SETOF record

但是你必须在每次调用时都提供一个列定义列表——让你回到你开始的地方。

  • 为每种不同的情况创建一个具有匹配返回类型的新函数。

但这就是您要避免的...

如果您必须编写“大量此类查询”,您可以改用查询生成器函数,它不会返回结果,而是您将在第二步中执行的 DDL 脚本。基本上是一个函数,它将可变部分作为参数并在您的示例中生成查询字符串RETURNS text......

这可能会变得非常复杂。必须考虑多个相互叠加的元级别,但这是绝对可能的。一定要大量使用美元报价来阻止报价的疯狂。

于 2012-06-22T01:32:37.777 回答