单列postgresql的组输出

时间:2014-02-18 11:25:34

标签: postgresql filter group-by

首先,我是一个完整的SQL菜鸟 - 提前感谢您提供的任何帮助。

我有一个FortiAnalyzer,它使用Postgres DB来存储防火墙日志。然后使用分析器报告使用情况等。

基本上我需要编写一个自定义查询,可以按每个用户排名前10位的网站/目的地的带宽显示前10名用户。

我可以从设备中获取所有相关信息,但我无法正确格式化输出。

我很满意输出显示用户名旁边前10个网站的用户名10次。然而,一等奖只是在A列中显示一次用户名,然后在B和C列中分别显示目的地址和带宽。

这是我到目前为止的查询:

select coalesce(nullifna(`user`), `src`) as user_src, 
coalesce(hostname, dstname, 'unknown') as web_site, 
sum(rcvd + sent)/1024 as bandwidth from $log 

where $filter and user is not null and status in ('passthrough', 'filtered') 

group by `user_src` , web_site order by user_src desc

一旦查询链接到报告图表,我就可以选择将输出限制为x值。例如,我可以将此限制为将user_src列限制为100(即每个有10个输出的10个用户)

我希望你明白这一点......如果没有,我会尽力回答任何问题。

1 个答案:

答案 0 :(得分:0)

我从website, user_src级别汇总的表开始。比排名前七的网站的顶级X用户并不困难。您需要使用window函数来获得所需的结果。

示例数据:

create table test (web_site varchar, user_src varchar, bandwidth numeric);

insert into test values 
  ('a','s1',18),
  ('b','s1',12),
  ('c','s1',13),
  ('d','s2',14),
  ('e','s2',15),
  ('f','s2',16),
  ('g','s3',17),
  ('h','s3',18),              
  ('i','s3',19)
;

为排名前Y的用户获取热门X网站:

with cte as (
  select
    user_src,
    web_site,
    bandwidth,
    dense_rank() over(order by site_bandwidth desc) as user_rank,
    dense_rank() over(partition by user_src order by bandwidth desc) as website_rank
  from
    test
    join (select user_src, sum(bandwidth) site_bandwidth from test group by user_src) a using (user_src)
)

select 
  * 
from 
  cte
where 
  user_rank <= 2
  and website_rank <=2
order by
  user_rank,
  website_rank

SQLFiddle