含窗口函数的SQL代码如何添加聚合函数?求代码调整优化建议
关于窗口函数SQL添加聚合函数及优化的解答
完全可以在现有包含窗口函数的SQL中添加聚合函数,根据你的需求不同有两种常用实现方案:
方案1:使用窗口聚合函数(保留所有原始行)
不需要加GROUP BY,不会压缩行数,在保留所有影片明细的同时,附加聚合计算结果,可直接和你现有的NTILE窗口函数共存,示例如下:
SELECT f.title, c.name AS category_name, f.rental_duration, -- 统计当前分类下的影片总数 COUNT(f.film_id) OVER (PARTITION BY c.category_id) AS category_film_total, -- 统计当前分类下的平均租赁时长 AVG(f.rental_duration) OVER (PARTITION BY c.category_id) AS category_avg_rental_time, -- 原有分位数计算逻辑 NTILE(4) OVER (ORDER BY f.rental_duration) AS standard_quartile, -- 统计所有符合条件影片的最长租赁时长 MAX(f.rental_duration) OVER () AS global_max_rental_time FROM film_category b JOIN category c ON c.category_id = b.category_id JOIN film f ON f.film_id = b.film_id WHERE c.name IN ('Animation', 'Children', 'Comedy', 'Family', 'Music') ORDER BY c.name, f.rental_duration;
方案2:先分组聚合再叠加窗口函数
如果你的需求是先按维度聚合得到汇总数据,再对汇总结果做窗口计算,可以用CTE/子查询先做聚合,外层再调用窗口函数:
WITH category_aggregate AS ( SELECT c.name AS category_name, COUNT(f.film_id) AS film_count, AVG(f.rental_duration) AS avg_rental_duration FROM film_category b JOIN category c ON c.category_id = b.category_id JOIN film f ON f.film_id = b.film_id WHERE c.name IN ('Animation', 'Children', 'Comedy', 'Family', 'Music') GROUP BY c.category_id, c.name ) SELECT *, NTILE(2) OVER(ORDER BY avg_rental_duration) AS duration_level FROM category_aggregate;
代码调整优化建议
- 简化冗余反引号:仅当表名/字段名是SQL关键字、包含特殊字符时才需要加反引号,你代码里的命名都是合法标识符,去掉多余反引号可读性更高
- 替换为表意明确的别名:把单字母别名
b替换为fc(对应film_category)、c替换为cat(对应category),后续维护代码不用反复核对别名对应关系 - 性能优化:如果表数据量较大,建议给
category.name、film_category.category_id、film_category.film_id添加索引,可大幅提升过滤和关联查询的效率 - 窗口函数按需分区:如果你需要的是每个分类内部的租赁时长分位数,给
NTILE的OVER子句加上PARTITION BY c.category_id即可,不需要全局排序分桶 - 排序逻辑优化:原SQL仅按租赁时长排序,建议增加分类名称作为第一排序字段,同分类的影片会排列在一起,结果可读性更高
内容的提问来源于stack exchange,提问作者Israel Owusu Ansah
相关产品推荐
相关产品推荐

