是否可以通过分区来限制窗口函数的结果,不使用子查询?这段代码位于 postgres/mysql.h 中。我正在寻找 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 Labortories,20]
我尝试了以下不起作用(向窗口函数添加了 limit 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;
最佳答案
I only want to show the first line of each of the window's partition. For example: lines with cnt: [3M,19],[Abbott Labortories,20]
这里实际上不需要窗口函数,因为第一行的 max_cnt
永远等于cnt
。而是使用DISTINCT ON
与 GROUP BY
结合使用.
SELECT DISTINCT ON ( expression [, ...] ) keeps only the first row of each set of rows where the given expressions evaluate to equal. The DISTINCT ON expressions are interpreted using the same rules as for ORDER BY (see above). Note that the “first row” of each set is unpredictable unless ORDER BY is used to ensure that the desired row appears first
SELECT DISTINCT ON(acct.name)
acct.name
, we.channel
, COUNT(*) cnt
FROM web_events we
JOIN accounts acct
ON we.account_id=acct.id
GROUP BY 1, 2
ORDER BY name, cnt DESC;
这是 sqlfiddle 中的快速演示。 http://sqlfiddle.com/#!17/57694/8
当我第一次开始使用DISTINCT ON
时我总是搞砸的一种方式就是保证 ORDER BY
中表达式的顺序子句以 DISTINCT ON
中的表达式开头。在上面的例子中 ORDER BY
以 acct.name
开头
如果第一个位置并列,则返回满足条件的第一行。这是不确定的。可以在 ORDER BY
中指定其他表达式。影响在此设置中返回哪些行。
示例:
ORDER BY name, cnt DESC, channel = 'direct'
将返回包含 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;
关于mysql/postgres窗口函数限制没有子查询的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51353443/