有没有可能在没有子查询的情况下,通过分区限制窗口函数的结果?这段代码在postgres/mysql中。我在寻找mysql和postgres的解决方案。
例如:假设连接与问题的重点无关。
select acct.name, we.channel, count(*) as cnt,
max(count(*)) over (partition by name order by count(*) desc) as max_cnt
from web_events we join accounts acct
on we.account_id=acct.id
group by acct.name, we.channel
order by name, max_cnt desc;
此查询的结果给出:
我只想显示每个窗口分区的第一行。例如:带有cnt的行:[3m,19],[abbott labtories,20]
我尝试了以下不起作用的操作(在窗口函数中添加了限制1):
select acct.name, we.channel, count(*) as cnt,
max(count(*)) over (partition by name order by count(*) desc limit 1) as max_cnt
from web_events we join accounts acct
on we.account_id=acct.id
group by acct.name, we.channel
order by name, max_cnt desc;
2条答案
按热度按时间m2xkgtsf1#
我只想显示每个窗口分区的第一行。例如:带有cnt的行:[3m,19],[abbott labtories,20]
实际上这里不需要窗口函数,因为第一行
max_cnt
永远平等cnt
. 而是使用DISTINCT ON
结合GROUP BY
.来自postgresql文档
select distinct on(表达式[,…])只保留给定表达式计算结果相等的每组行的第一行。distinct on表达式使用与order by相同的规则进行解释(见上文)。请注意,每个集合的“第一行”是不可预测的,除非使用order by来确保所需的行首先出现
这里有一个sqlfiddle的快速演示。http://sqlfiddle.com/#!17/57694/8
我刚开始用的时候总是搞砸
DISTINCT ON
是为了确保ORDER BY
子句以DISTINCT ON
. 在上面的例子中ORDER BY
开始于acct.name
如果第一个位置有平局,则返回符合条件的第一行。这是不确定的。可以在中指定其他表达式ORDER BY
以影响在此设置中返回的行。例子:
将返回包含
facebook
,如果为给定帐户,则facebook
以及direct
产量相同cnt
.但是,请注意,使用这种方法,不可能返回为第一个位置绑定的所有行,即两行都包含
facebook
&direct
(不使用子查询)。DISTINCT ON
可以与组合在同一语句中GROUP BY
s(上例)和WINDOW FUNCTIONS
(示例如下)。这个DISTINCT ON
子句在LIMIT
.例如,下面的查询(尽管毫无意义)显示了
DISTINCT ON
与WINDOW FUNCTION
. 它将在每个max_cnt
```SELECT DISTINCT ON(mxcnt)
acct.name
, we.channel
, COUNT() cnt
, MAX(COUNT()) OVER (PARTITION BY acct.name) mxcnt
FROM web_events we
JOIN accounts acct
ON we.account_id=acct.id
GROUP BY 1, 2
ORDER BY mxcnt, cnt DESC;
9gm1akwq2#
使用子查询。如果您只想要一行(即使有领带),那么使用
row_number()
:你可以用
rank()
如果您希望一个帐户有多个行,则在发生关系时。