繁体   English   中英

根据窗口函数过滤行

[英]Filter rows based on window function

最近,我看到了一位用户,他是唯一获得一些徽章的用户。

奇怪的是,我前往data.se并寻找类似的例子( data.se - 单一授予徽章

select count(*) as awarded,
       name, class
from badges
group by name, class
having count(*) = 1

更进一步,我还希望看到拥有这些徽章的用户( data.se - 计数授予徽章和用户

select count(*) over (partition by b.name, b.class) as awarded,
       b.name, b.class, u.displayname
from badges b
join users u on u.id = b.userid

这给了我所有条目,不仅是单个拥有条目,例如count(*) = 1 要获得这些,我必须使用CTE或子查询,例如( data.se - 单一授予徽章和用户

with q as (select count(*) over (partition by b.name, b.class) as awarded,
                  b.name, b.class, u.displayname
           from badges b
           join users u on u.id = b.userid)
select name, class, displayname
from q
where awarded = 1

最后两个查询的缺点是性能。 (非缓存)查询group by/having查询需要大约20倍的简单group by/having 使用子查询没有任何改进。


我知道,你不能在where或having子句中使用window函数 ,也不能在第二个查询中说where awarded = 1

是否有更快更简单的查询,甚至可能没有CTE或子查询? 我给一个(用CTE)作为我自己的答案,但希望看到替代解决方案。

一种解决方案是group by/having查询作为CTE进行group by/having并与徽章和用户表联接data.se - 单个授予的徽章和用户

with awarded as (select count(*) as num,
                        name, class
                 from badges
                 group by name, class
                 having count(*) = 1)
select b.name, b.class, u.displayname
from badges b
join awarded a on a.name = b.name and a.class = b.class
join users u on u.id = b.userid

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM