ITPub博客

首页 > 数据库 > MySQL > 安信6主管2540437PostgreSQL:窗口函数

安信6主管2540437PostgreSQL:窗口函数

原创 MySQL 作者:杏悦2主管2540437 时间:2020-12-11 14:27:10 0 删除 编辑

语法

1
2
3
4
5
6
7
8
function_name ([expression [, expression ...]]) [FILTER ( WHERE  filter_clause)]
     OVER (window_definition)
     
window_definition:
   [existing_window_name]
   [PARTITION  BY  expression [, ...]]
   [ ORDER  BY  expression [ ASC  |  DESC  | USING operator] [NULLS { FIRST  |  LAST  }] [, ...]]
   [frame_clause]
  • OVER:表示窗口函数的关键字

  • PARTITION BY:对查询返回的结果集进行分组,之后窗口函数处理分组的数据。

  • ORDER BY:设定结果集的分组数据排序

测试数据创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- 创建成绩表
create  table  score(
id serial  PRIMARY  key ,
subject    character (32),
stu_name   character (32),
grade      NUMERIC (3,0)
);
  
-- 插入数据
INSERT  INTO  SCORE(subject,stu_name,grade)  values 
( '语文' , '小王' ,80),
( '语文' , '小张' ,70),
( '语文' , '小李' ,80),
( '英语' , '小王' ,90),
( '英语' , '小张' ,70),
( '英语' , '小李' ,50),
( '数学' , '小王' ,100),
( '数学' , '小张' ,70),
( '数学' , '小李' ,65);

avg() OVER()

聚合函数后接 over属性的窗口函数表示在一个查询结果集上应用聚合函数。

查询没名学生学习成绩并且显示课程的平均分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- 对比
-- 先算课程的平均分,再用 score 表与平均分表关联查询
SELECT  s.stu_name, s.subject, s.grade, v.avgscore
   FROM  score s
   LEFT  JOIN  (
     SELECT  subject,  avg (grade)  AS  avgscore
       FROM  score
      GROUP  BY  subject
   ) v  ON  s.subject = v.subject
  ORDER  BY  s.stu_name, s.subject
  
-- 使用窗口函数
SELECT  s.stu_name, s.subject, grade,
        AVG (grade) OVER (PARTITION  BY  subject)  AS  avgscore
   FROM  score s
  ORDER  BY  s.stu_name, s.subject

row_number()

对结果集分组后的数据标注行号,从 1 开始

1
2
3
4
5
SELECT  row_number() OVER (PARTITION  BY  subject  ORDER  BY  score  desc ), *
   FROM  score;
   
SELECT  row_number() OVER ( ORDER  BY  score  desc )  as  rownum, *
   FROM  score;

rank()

当组内某行字段值相同时,行号重复并且行号产生间隙

1
2
SELECT  rank() OVER (PARTITION  BY  subject  ORDER  BY  score  desc ), *
   FROM  score;

dense_rank()

当组内某行字段值相同时,虽然行号重复,但行号不产生间隙

1
2
SELECT  dense_rank() OVER (PARTITION  BY  subject  ORDER  BY  score  desc ), *
   FROM  score;

lag()

获取行偏移 offset 那行某个字段的数据,语法如下:

1
lag(value anyelement [, offset  integer  [,  default  anyelement]])
  • value:指定要返回记录的字段。 

  • offset:指行偏移量,可以是正整数或负整数,正整数表示取值结果集中向上偏移的记录,负整数表示取结果集中向下偏移的记录,默认值为 1。

  • default:指如果不存在 offset 偏移的行时用默认值填充,default 值默认为 null。

获取向上偏移 1 行记录的 id 值

1
2
SELECT  lag(id, 1) OVER (PARTITION  BY  subject  ORDER  BY  score  desc ), *
   FROM  score;

first_value()

用来取结果集每一个分组的第一行数据的字段值

score 表按课程分组后取分组的第一行的分数

1
2
SELECT  first_value(score) OVER (PARTITION  BY  subject  ORDER  BY  score  desc ), *
   FROM  score;

last_value()

用来取结果集每一个分组的最后一行数据的字段值

score 表按课程分组后取分组的最后一行的分数

1
2
SELECT  last_value(score) OVER (PARTITION  BY  subject  ORDER  BY  score  desc ), *
   FROM  score;

nth_value()

用来取结果集每一个分组的指定行数据的字段值

1
last_value(value  any , nth  integer )
  • value:指定表的字段

  • nth:指定结果集分组数据中的第几行,如果不存在则返回空

score 表按课程分组后取分组的第二行的分数

1
2
SELECT  nth_value(score, 2) OVER (PARTITION  BY  subject  ORDER  BY  score  desc ), *
   FROM  score;

别名

如果 SQL 中需要多次使用窗口函数,可以使用窗口函数别名:

1
SELECT  ...  FROM  ... WINDOW window_name  AS  ( window_definition )[, ...]
1
2
3
SELECT  avg (score) OVER(r),  sum (score) OVER(r), *
   FROM  score
  WINDOW r  as  (PARTITION  BY  subject  ORDER  BY  score  desc )


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69990215/viewspace-2741437/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2020-12-10

  • 博文量
    2
  • 访问量
    1393