【SQL查询】获取分区里最大和最小值_first_value/last_value

FIRST_VALUE | LAST_VALUE

1. 语法

FIRST_VALUE | LAST_VALUE ( expression [ IGNORE NULLS | RESPECT NULLS ] ) OVER ( [ PARTITION BY expr_list ] [ ORDER BY order_list frame_clause ] )

2. 参数说明

【expression】:对其执行函数的目标列或表达式。

【IGNORE NULLS】:将此选项与 FIRST_VALUE 结合使用时,该函数返回不为 NULL 的框架中的第一个值(如果所有值为 NULL,则返回 NULL)。将此选项与 LAST_VALUE 结合使用时,该函数返回不为 NULL 的框架中的最后一个值(如果所有值为 NULL,则返回 NULL)。

【RESPECT NULLS】:指示 Amazon Redshift 应包含 null 值以确定要使用的行。如果您未指定 IGNORE NULLS,则默认情况下不支持 RESPECT NULLS。

【OVER】:引入函数的窗口子句。

【PARTITION BY expr_list】:依据一个或多个表达式定义函数的窗口。

【ORDER BY order_list】:对每个分区中的行进行排序。如果未指定 PARTITION BY 子句,则 ORDER BY 对整个表进行排序。如果指定 ORDER BY 子句,则还必须指定frame_clause

3.示例

  • 初始化脚本

/*创建表格(emp)*/
create table emp(
EMPNO NUMBER(4) primary key,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7,2),
COMM NUMBER(7,2),
DEPTNO NUMBER(2)
);

/*向表格中插入数据*/
insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7369, ‘SMITH‘, ‘CLERK‘, 7902, to_date(‘1980-12-17‘,‘YYYY-MM-DD‘), 800, NULL, 20);

insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7499, ‘ALLEN‘, ‘SALESMAN‘, 7698, to_date(‘1981-02-20‘,‘YYYY-MM-DD‘), 1600, 300, 30);

insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7521, ‘WARD‘, ‘SALESMAN‘, 7698, to_date(‘1981-02-22‘,‘YYYY-MM-DD‘), 1250, 500, 20);

insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7566, ‘JONES‘, ‘MANAGER‘, 7839, to_date(‘1981-04-02‘,‘YYYY-MM-DD‘), 2975, NULL, 20);

insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7654, ‘MARTIN‘, ‘SALESMAN‘, 7698, to_date(‘1981-09-28‘,‘YYYY-MM-DD‘), 1250, 1400, 30);

insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7698, ‘BLAKE‘, ‘MANAGER‘, 7839, to_date(‘1981-05-01‘,‘YYYY-MM-DD‘), 2845, NULL, 30);

insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7782, ‘CLARK‘, ‘MANAGER‘, 7839, to_date(‘1981-06-09‘,‘YYYY-MM-DD‘), 2450, NULL, 10);

insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7788, ‘SCOTT‘, ‘ANALYST‘, 7566, to_date(‘1987-04-19‘,‘YYYY-MM-DD‘), 3000, NULL, 20);

insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7839, ‘KING‘, ‘PRESIDENT‘, NULL, to_date(‘1981-11-17‘,‘YYYY-MM-DD‘), 5000, NULL, 10);

insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7844, ‘TURNER‘, ‘SALESMAN‘, 7698, to_date(‘1981-09-08‘,‘YYYY-MM-DD‘), 1500, 0, 30);

insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7876, ‘ADAMS‘, ‘CLERK‘, 7788, to_date(‘1987-05-23‘,‘YYYY-MM-DD‘), 1100, NULL, 20);

insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7900, ‘JAMES‘, ‘CLERK‘, 7698, to_date(‘1981-12-03‘,‘YYYY-MM-DD‘), 950, NULL, 30);

insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7902, ‘FORD‘, ‘ANALYST‘, 7566, to_date(‘1981-12-03‘,‘YYYY-MM-DD‘), 3000, NULL, 20);

insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7934, ‘MILLER‘, ‘CLERK‘, 7782, to_date(‘1982-01-23‘,‘YYYY-MM-DD‘), 1300, NULL, 10);

commit;

  • FIRST_VALUE: 获取每个部门最高的工资
select emp.*, first_value(emp.sal) over(partition by emp.deptno order by emp.sal desc) "最高工资" from emp

结果:

  • LAST_VALUE:获取每个部门最低工资
select emp.*, last_value(emp.sal) over(partition by emp.deptno order by emp.sal desc) "最低工资" from emp

结果:

  

 和预期的结果不一样,系统未获取分区中最小的工资。根本原因如下:last_value()默认统计范围是:rows between unbounded preceding and current row, 而应该采用以下的统计范围: rows between unbounded preceding and unbounded following(两者统计范围的差别,可参考注释)。修改代码如下:

select emp.*, last_value(emp.sal) over(partition by emp.deptno order by emp.sal desc  rows between unbounded preceding and unbounded following) "最低工资" from em

结果:

  

 注:

  unbounded:无界限

preceding:从分区第一行头开始,则为 unbounded。 N为:相对当前行向前的偏移量

following :与preceding相反,到该分区结束,则为 unbounded。N为:相对当前行向后的偏移量

current row:顾名思义,当前行,偏移量为0

 

原文地址:https://www.cnblogs.com/zhuhaiying/p/12222324.html

时间: 2024-10-10 09:44:46

【SQL查询】获取分区里最大和最小值_first_value/last_value的相关文章

sql查询重复记录并取对应最小值

原表(aa): id   a                      b 1    22                    456 2    22                    256 3    22                    268 4    23                    236 5    23                    358 要求查询 a字段重复记录取对应b中最小值 要显示结果: 22                    256 23 

根据sql查询获取sql查询结果集列的元数据

public List<DatasetColumn> queryDatasetColumns(String datasetId) { if(StringUtil.isEmpty(datasetId)) { return new ArrayList<DatasetColumn>(); } DatasetDefine dataSet = this.findById(DatasetDefine.class, datasetId); String sql = "select * 

将Sql查询语句获取的数据插入到List列表里面

Sql查询语句获取的数据是分格式的,我们还用SqlDataReader来做,然后用IDataReader来接收读取,以下是代码: //我想查询一个用户表的信息,该用户有姓名,密码,信息三列 //1.定义一个用户类型的List数组,userInfo类的代码在下方 List<userInfo> userInfo = new List<userInfo>(); //2.我们要读取查询语句的数据,并且保存了.这里我们将使用IDataReader语句 //数据库类的实例,类的代码在下方 DB

获取动态SQL查询语句返回值(sp_executesql)

在写存储过程时经常会遇到需要拼接SQL语句的情况,一般情况下仅仅是为了执行拼接后的语句使用exec(@sql)即可. 而今天的一个存储过程却需要获取动态SQL的查询结果. 需求描述:在某表中根据Id值查询Cost值(表名不确定但表结构确定,如下面的Product表) 如果不考虑获取返回值,我们这样写即可: declare @tableName varchar(50) declare @id varchar(10) declare @cost numeric(18,2) declare @sql

Java 获取SQL查询语句结果

step1:构造连接Class.forName("com.mysql.jdbc.Driver"); Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/db","root","123"); step2:构造语句String sql = "select username,password from t_user where

在erb文件里也可以进行sql查询

<p><%= course =Course.find_by_id(params[:id]) %></p> 在erb文件里也可以进行sql查询

(转)经典SQL查询语句大全

一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- 创建 备份数据的 device USE master EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat' --- 开始 备份 BACKUP DATABASE pubs TO testBack 4.说明:创建

经典SQL查询语句大全

一.基础1.说明:创建数据库CREATE DATABASE database-name2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备份数据的 deviceUSE masterEXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'--- 开始 备份BACKUP DATABASE pubs TO testBack4.说明:创建新表create ta

SQL查询语句大全(转)

转自https://www.cnblogs.com/chenglc/p/8421492.html 重点参考https://blog.csdn.net/g1418377085/article/details/77504076/ 一.基础1.说明:创建数据库CREATE DATABASE database-name2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备份数据的 deviceUSE masterEXEC sp_addumpdevi