mysql/postgres窗口函数限制没有子查询的结果

标签 mysql sql postgresql window-functions partition

是否可以通过分区来限制窗口函数的结果,不使用子查询?这段代码位于 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;

此查询的结果给出:

output

我只想显示每个窗口分区的第一行。 例如:带有 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 ONGROUP BY 结合使用.

来自postgresql documentation

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 BYacct.name 开头

如果第一个位置并列,则返回满足条件的第一行。这是不确定的。可以在 ORDER BY 中指定其他表达式。影响在此设置中返回哪些行。

示例:

ORDER BY name, cnt DESC, channel = 'direct'

将返回包含 facebook 的行,如果对于给定帐户,则 facebookdirect产生相同的 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/

相关文章:

PHP postgreSQL 执行查询

html - 在 Windows 中安装 OTRS 3.2

mysql - sql 中最常出现的值

php - 使用 jQuery、PHP、MySQL 选择值

php - 如何在 PHP 中显示 MySQL Select 语句结果

sql - 在 PostgreSQL 中使用 SELECT CASE WHEN 来选择从分割中产生的最小多边形

mysql - 如何连接到另一台主机上的MySQL服务器?

php - 为什么在 UPDATErequest 中请求 +1 会得到 +2?

php - 3 表 1 嵌套结果查询 - Mysql - Php

postgresql - 斯卡拉和玩! & Slick & PostgreSQL 自增