![](/img/trans.png)
[英]How to filter rows in SQL statement for aggregate function by window function?
[英]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.