Sql 带有限制子句的窗口函数

Sql 带有限制子句的窗口函数,sql,postgresql,window-functions,Sql,Postgresql,Window Functions,考虑到这个团队数据集 id | team_name | points 1 | A | 10 2 | B | 20 3 | C | 30 4 | D | 40 5 | E | 50 我可以使用这个查询和一个窗口函数来获得前三名球队的平均值 with top_3 as( select * from teams order by points desc limit 3 ) select

考虑到这个团队数据集

id | team_name | points
1  | A         | 10
2  | B         | 20
3  | C         | 30
4  | D         | 40
5  | E         | 50
我可以使用这个查询和一个窗口函数来获得前三名球队的平均值

with top_3 as(
  select * 
  from teams 
  order by points desc 
  limit 3
)

select *, avg(points) over() as top3_average
from top_3
是否可以仅对数据集中的前3行使用窗口函数

我试过了,但肯定不行

OVER(... limit 3)
这是一张工作票

我知道我可以用这样的子查询来实现这一点。我更感兴趣的是学习是否可以通过窗口功能实现这一点

with top_3 as(
  select * ,row_number() over(order by points desc) rn 
  from teams 


) select * form top_3 where rn<=3
是可能使用行数窗口功能

with top_3 as(
  select * ,row_number() over(order by points desc) rn 
  from teams 


) select * form top_3 where rn<=3
是可能使用行数窗口功能

with top_3 as(
  select * ,row_number() over(order by points desc) rn 
  from teams 


) select * form top_3 where rn<=3

不,不是真的。无法轻松指定仅包含前三行的帧。你可以在第一行中得到平均值,然后在其他地方设置空值,但这似乎是一个糟糕的想法:

select *, 
    avg(points) OVER (ORDER BY points desc ROWS BETWEEN UNBOUNDED PRECEDING AND 2 FOLLOWING) 
    * CASE WHEN row_number() OVER (ORDER BY points desc) = 1 THEN 1 ELSE null END
FROM teams;
 id | team_name | points |      ?column?
----+-----------+--------+---------------------
  6 | F         |     60 | 50.0000000000000000
  5 | E         |     50 |
  4 | D         |     40 |
  3 | C         |     30 |
  2 | B         |     20 |
  1 | A         |     10 |
(6 rows)

不,不是真的。无法轻松指定仅包含前三行的帧。你可以在第一行中得到平均值,然后在其他地方设置空值,但这似乎是一个糟糕的想法:

select *, 
    avg(points) OVER (ORDER BY points desc ROWS BETWEEN UNBOUNDED PRECEDING AND 2 FOLLOWING) 
    * CASE WHEN row_number() OVER (ORDER BY points desc) = 1 THEN 1 ELSE null END
FROM teams;
 id | team_name | points |      ?column?
----+-----------+--------+---------------------
  6 | F         |     60 | 50.0000000000000000
  5 | E         |     50 |
  4 | D         |     40 |
  3 | C         |     30 |
  2 | B         |     20 |
  1 | A         |     10 |
(6 rows)

是的,你是对的,但这仍然需要两个查询。是的,你是对的,但这仍然需要两个查询。我认为这不可能在一个步骤中实现,因为限制是在执行顺序的窗口函数之后应用的。有一些选项可以不受限制地执行此操作,但它们仍然需要两个步骤…1。获取样本集2。应用聚合。如果是我,我会将子查询从WHERE子句移动到from子句,或者使用您的CTE示例。我只知道OVER子句中的PARTITION BY和ORDER BY。哦,是的,正如Jeremy提到的,OVER子句中存在两行。不过,我希望子查询的性能会更好。我认为这不可能在一个步骤中实现,因为限制是在执行顺序中的窗口函数之后应用的。有一些选项可以不受限制地执行此操作,但它们仍然需要两个步骤…1。获取样本集2。应用聚合。如果是我,我会将子查询从WHERE子句移动到from子句,或者使用您的CTE示例。我只知道OVER子句中的PARTITION BY和ORDER BY。哦,是的,正如Jeremy提到的,OVER子句中存在两行。不过,我希望子查询的性能会更好。是的,我同意,这看起来不是很优雅,但是谢谢你的提示,我同意,这看起来不是很优雅,但是谢谢你的提示