zoukankan      html  css  js  c++  java
  • PostgreSQL 窗口函数 ( Window Functions ) 如何使用?

    一、为什么要有窗口函数


    我们直接用例子来说明,这里有一张学生考试成绩表testScore

    现在有个需求,需要查询的时候多出一列subject_avg_score,为此科目所有人的平均成绩,好跟每个人的成绩做对比。

    传统方法肯定是用聚合,但是写起来很麻烦也很累赘,这时候窗口函数就排上了用场。

    因为窗口函数不会像聚合一样将参与计算的行合并成一行输出,而是将计算出来的结果带回到了计算行上。

    二、窗口函数的使用


    1、聚合和窗口函数的区别

    聚合:聚合函数(sum,min,avg……) + GROUP BY

    窗口函数:聚合函数(sum,min,avg……) + OVER ( …… )

    2、使用

    还用上面的例子:

    (1) 取每个不同科目的平均值subject_avg_score [这正是上面提到的需求]

    这里的 OVER 里用到了 PARTITION BY

    SELECT *, 
           avg("score") OVER (PARTITION BY "subject") as "subject_avg_score"
    FROM "testScore"  
    

    (2) 取所有成绩的平均值subject_avg_score

    这里的 OVER 里为空

    SELECT *, 
           avg("score") OVER () as "subject_avg_score"
    FROM "testScore"  
    

    (3) 取此人该科目成绩班上排第几名subject_rank_score

    这里的 OVER 里用到了 PARTITION BY + ORDER BY

    ORDER BY 只能用在一些特殊的聚合函数里,比如这里的 rank()

    SELECT *, 
            avg("score") OVER (PARTITION BY "subject") as "subject_avg_score",
    				rank() OVER (PARTITION BY "subject" ORDER BY "score" DESC) as "subject_rank_score" 
    FROM "testScore"  
    

    拓展知识:rank()、dense_rank()、row_number() 区别

    rank() 最适合用来做排名的功能,它是若两人并列第一,那第三个人就排名第三

    dense_rank() 跟 rank() 的区别是,若两人并列第一,那第三个人紧随其后排名第二

    row_number() 则单纯是序号,所以不会出现多个人并列的情况。

    (4) 提取 OVER 变量

    如果在 sql 里写了很多重复的 OVER(),可以提取成一个 window 变量,简化代码。

    SELECT *, 
            avg("score") OVER window_frame as "subject_avg_score",
            avg("score") OVER window_frame as "subject_avg_score_2",
            avg("score") OVER window_frame as "subject_avg_score_3"
    FROM "testScore"  
    window window_frame as (PARTITION BY "subject")
    


    参考资料

    官方文档:http://www.postgres.cn/docs/9.3/tutorial-window.html

    Postgresql窗口函数(一)

    Postgresql窗口函数(二)

  • 相关阅读:
    ES6~Promise的原理及使用二 理解Promise规范(copy自:https://www.cnblogs.com/lvdabao/p/5320705.html?utm_source=tuicool&utm_medium=referral)
    Google的Python代码格式化工具YAPF详解
    在ubuntu上使用QQ的经历
    Ubuntu 14.04 下安装Skype
    pip install lxml mysql-python error
    情人节的宠物-测试小工具
    戴维营收集
    工作日志(10.29)
    求职面试
    面试题集(转载)
  • 原文地址:https://www.cnblogs.com/xjnotxj/p/11198566.html
Copyright © 2011-2022 走看看