mysql/postgres window 没有子查询的函数限制结果
mysql/postgres window function limit result without subquery
是否可以限制 window 函数的结果,有分区,没有子查询?此代码在 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;
这个查询的结果给出:
我只想显示每个 window 分区的第一行。
例如:带有 cnt 的行:[3M,19],[Abbott Labortories,20]
我尝试了以下无效的方法(向 window 函数添加了限制 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;
使用子查询。如果您只想要一行(即使有平局),则使用 row_number()
:
select name, channel, cnt
from (select acct.name, we.channel, count(*) as cnt,
row_number() over (partition by acct.name order by count(*) desc) as seqnum
from web_events we join
accounts acct
on we.account_id = acct.id
group by acct.name, we.channel
) wea
order by name;
如果您希望一个帐户有多个行,您可以使用 rank()
,以防出现平局。
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]
这里实际上不需要 window 函数,因为第一行的 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
开头
如果第一名出现平局,则将 return 编辑满足条件的第一行。这是不确定的。可以在 ORDER BY
中指定额外的表达式来影响在此设置中 return 编辑了哪些行。
示例:
ORDER BY name, cnt DESC, channel = 'direct'
将 return 包含 facebook
的行,如果对于给定帐户,facebook
和 direct
产生相同的 cnt
.
但是,请注意,使用这种方法,不可能 return 所有与第一位置并列的行,即包含 facebook
和 direct
的两行(没有使用子查询)。
DISTINCT ON
可以与 GROUP BY
s(上例)和 WINDOW FUNCTIONS
(下例)组合在同一语句中。 DISTINCT ON
子句在 LIMIT
.
之前进行逻辑计算
例如,以下查询(但毫无意义)显示了 DISTINCT ON
与 WINDOW FUNCTION
的组合。它将 return 每个 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;
是否可以限制 window 函数的结果,有分区,没有子查询?此代码在 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;
这个查询的结果给出:
我只想显示每个 window 分区的第一行。 例如:带有 cnt 的行:[3M,19],[Abbott Labortories,20]
我尝试了以下无效的方法(向 window 函数添加了限制 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;
使用子查询。如果您只想要一行(即使有平局),则使用 row_number()
:
select name, channel, cnt
from (select acct.name, we.channel, count(*) as cnt,
row_number() over (partition by acct.name order by count(*) desc) as seqnum
from web_events we join
accounts acct
on we.account_id = acct.id
group by acct.name, we.channel
) wea
order by name;
如果您希望一个帐户有多个行,您可以使用 rank()
,以防出现平局。
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]
这里实际上不需要 window 函数,因为第一行的 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
如果第一名出现平局,则将 return 编辑满足条件的第一行。这是不确定的。可以在 ORDER BY
中指定额外的表达式来影响在此设置中 return 编辑了哪些行。
示例:
ORDER BY name, cnt DESC, channel = 'direct'
将 return 包含 facebook
的行,如果对于给定帐户,facebook
和 direct
产生相同的 cnt
.
但是,请注意,使用这种方法,不可能 return 所有与第一位置并列的行,即包含 facebook
和 direct
的两行(没有使用子查询)。
DISTINCT ON
可以与 GROUP BY
s(上例)和 WINDOW FUNCTIONS
(下例)组合在同一语句中。 DISTINCT ON
子句在 LIMIT
.
例如,以下查询(但毫无意义)显示了 DISTINCT ON
与 WINDOW FUNCTION
的组合。它将 return 每个 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;