3

我的查询如下所示:

SELECT mthreport.*
FROM crosstab
('SELECT 
to_char(ipstimestamp, ''mon DD HH24h'') As row_name, 
varid::text || log.varid || ''_'' || ips.objectname::text As bucket, 
COUNT(*)::integer As bucketvalue
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 = 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, bucket        
ORDER BY to_char(ipstimestamp, ''yyyy MM DD HH24h''), row_name, objectid, bucket' )

As mthreport(item_name text,  varid_37551 integer, 
            varid_27087  integer , 
            varid_50876  integer , 
            varid_45096  integer , 
            varid_54708  integer , 
            varid_47475  integer , 
            varid_54606  integer , 
            varid_25528  integer , 
            varid_54729  integer , 
            varid_29469 integer)

可以使用以下连接字符串针对测试表测试查询:“host=bellariastrasse.com port=5432 dbname=IpsLogging user=guest password=guest”

该查询在语法上是正确的并且运行良好。我的问题是 COUNT(*) 值总是填充最左边的列。然而,在许多情况下,左列应该有一个零或 NULL,并且只有第 2(或第 n)列应该被填充。我的大脑正在融化,我无法弄清楚出了什么问题!

4

1 回答 1

2

您的问题的解决方案是使用带有两个参数crosstab()的变体。

第二个参数(另一个查询字符串)生成输出列的列表,以便正确分配数据查询(第一个参数)中的 NULL 值。

检查tablefunc 扩展的手册,特别是crosstab(text, text)

交叉表的单参数形式的主要限制是它对组中的所有值都进行相同的处理,将每个值插入到第一个可用列中。如果您希望值列与特定的数据类别相对应,并且某些组可能没有某些类别的数据,则效果不佳。交叉表的双参数形式通过提供与输出列对应的类别的显式列表来处理这种情况。

强调我的。我最近在这里这里这里发布了几个相关的答案。

于 2012-06-17T23:55:45.600 回答