窗口函数避坑指南

本文详细介绍了窗口函数在SQL查询中的执行顺序和限制,强调了不能在WHERE、HAVING和GROUP BY子句中直接使用窗口函数。通过错误和正确代码示例,展示了如何在查询中正确应用窗口函数,包括在ORDER BY中的使用,以及与GROUP BY结合的场景。同时,提供了利用窗口函数进行排名、计算环比和分组聚合的方法,帮助开发者避免常见陷阱,提升SQL查询效率。
摘要由CSDN通过智能技术生成

窗口函数避坑指南:

窗口函数执行顺序:

  • FROM
  • WHERE
  • GROUP BY
  • 聚合函数
  • HAVING
  • 窗口函数
  • SELECT
  • DISTINCT
  • UNION
  • ORDER BY
  • OFFSET
  • LIMIT

不能在WHERE子句中使用窗口函数:

错误版本演示:

SELECT 
  id, 
  final_price 
FROM auction 
WHERE final_price > AVG(final_price) OVER();

报错信息:

SELECT 
  id, 
  final_price 
FROM auction 
WHERE final_price > AVG(final_price) OVER()
> 3593 - You cannot use the window function 'avg' in this context.'
> 时间: 0.005s

正确代码:

SELECT
  id,
  final_price 
FROM (
  SELECT
    id,
    final_price,
    AVG(final_price) OVER() AS avg_final_price
  FROM auction) c
WHERE final_price > avg_final_price

不能在HAVING子句中使用窗口函数:

错误版本展示:

SELECT 
  country, 
  AVG(final_price) 
FROM auction 
GROUP BY country 
HAVING AVG(final_price) > AVG(final_price) OVER ();

正确版本展示:

SELECT
  country,
  AVG(final_price) 
FROM auction 
GROUP BY country 
HAVING AVG(final_price) > (SELECT AVG(final_price) FROM auction);

不能在GROUP BY子句中使用窗口函数:

错误版本演示:

SELECT 
  NTILE(4) OVER(ORDER BY views DESC) AS quartile, 
  MIN(views), 
  MAX(views) 
FROM auction 
GROUP BY NTILE(4) OVER(ORDER BY views DESC);

正确版本演示:

SELECT
  quartile,
  MIN(views),
  MAX(views)
FROM
  (SELECT
    views,
    ntile(4) OVER(ORDER BY views DESC) AS quartile
  FROM auction) c
GROUP BY quartile;

在ORDER BY中使用窗口函数:

SELECT
  id,
  views,
  NTILE(4) OVER(ORDER BY views DESC) AS quartile
FROM auction
ORDER BY NTILE(4) OVER(ORDER BY views DESC);

窗口函数与GROUP BY一起使用:

错误演示:

SELECT 
  category_id,
  final_price, 
  AVG(final_price) OVER() 
FROM auction;

正确演示:

SELECT
  category_id,
  MAX(final_price) AS max_final, 
  AVG(MAX(final_price)) OVER() AS `avg`
FROM auction
GROUP BY category_id;

Rank时使用聚合函数:

SELECT
  country,
  COUNT(id),
  RANK() OVER(ORDER BY COUNT(id) DESC) AS `rank`
FROM auction
GROUP BY country;

利用GROUP BY计算环比:

SELECT
  ended,
  SUM(final_price) AS sum_price,
  LAG(SUM(final_price)) OVER(ORDER BY ended) AS `lag`
FROM auction
GROUP BY ended
ORDER BY ended;

对GROUP BY分组后的数据使用 PARTITION BY:

select country,
    ended,
    sum(views) views_on_day,
    sum(sum(views))over (PARTITION BY country) views_country
from auction group by country,ended;

总结:

  • 窗口函数只能出现在SELECT和ORDER BY子句中
  • 如果查询的其他部分(WHERE,GROUP BY,HAVING)需要窗口函数,请使用子查询,然后在子查询中在使用窗口函数
  • 如果查询使用聚合或GROUP BY,请记住窗口函数只能处理分组后的结果,而不是原始的表数据
  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值