暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Mysql8.0窗口函数用法

Mysql8.0窗口函数用法

一.Mysql8.0安装

一、环境准备:

1.目录创建:

mkdir -p /data/{software,mysql}

mkdir -p /data/mysql/{data,log,tmp}

2.用户创建:

useradd mysql

3.安装依赖包:

yum install perl perl-devel perl-Data-Dumper libaio-devel -y

二、安装:

1.下载包文件:

cd /data/software/

wget https://cdn.mysql.com/archives/mysql-8.0/mysql-8.0.34-linux-glibc2.12-x86_64.tar.xz

tar -xvf mysql-8.0.34-linux-glibc2.12-x86_64.tar.xz

ln -s /data/software/mysql-8.0.34-linux-glibc2.12-x86_64 /usr/local/mysql

2.权限赋值:

chown -R mysql:mysql /usr/local/mysql /data/mysql/*

三、配置文件:

参数可以根据实际需求进行调配

vi /etc/my.cnf

[client]

port = 3306

socket = /data/mysql/tmp/mysql.sock

[mysql]

prompt="\u@db \R:\m:\s [\d]> "

no-auto-rehash

[mysqld]

user = mysql

port = 3306

basedir = /usr/local/mysql

datadir = /data/mysql/data

socket = /data/mysql/tmp/mysql.sock

tmpdir =

pid-file = /data/mysql/tmp/mysql.pid

character-set-server=utf8

collation-server = utf8_general_ci

sql_mode=‘NO_UNSIGNED_SUBTRACTION,NO_ENGINE_SUBSTITUTION’

open_files_limit = 65535

innodb_open_files = 65535

back_log=1024

max_connections = 512

max_connect_errors=1000000

interactive_timeout=300

wait_timeout=300

max_allowed_packet = 1024M

secure_file_priv=’’

log-error=/data/mysql/log/error.log

slow_query_log=ON

slow_query_log_file=/data/mysql/log/slow_mysql.log

long_query_time=1

innodb_flush_log_at_trx_commit=1

innodb_log_file_size =1G

innodb_log_files_in_group=3

innodb_log_group_home_dir=./

sync_binlog = 1

binlog_cache_size = 16M

max_binlog_cache_size = 1G

max_binlog_size=1G

expire_logs_days = 30

log-bin-trust-function-creators=1

log-bin= /data/mysql/log/binlog-mysql

binlog_format=row

binlog_row_image=full

server-id = 1

大小根据实际情况而定

innodb_buffer_pool_size=1G

innodb_buffer_pool_instances=2

四、初始化Mysql

1.初始化操作:

/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql --datadir=/data/mysql/data --user=mysql --initialize

2.查看随机密码:可以看到我们的初始密码为 “Eiv*/Dy!I44t”

[root@node1 data]# cat /data/mysql/log/error.log | grep password

2019-02-21T10:45:24.067928Z 1 [Note] A temporary password is generated for root@node1: Eiv*/Dy!I44t

五、启动mysql:

/usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &

六、修改密码,设置环境变量以及自启动

[root@node1 log]# echo ‘export PATH=/usr/local/mysql/bin:$PATH’ >> /etc/profile

[root@node1 ~]# source /etc/profile

[root@node1 ~]# /usr/local/mysql/bin/mysqladmin -uroot -p password

Enter password:

New password:

Confirm new password: Password123

[root@node1 ~]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld

[root@node1 ~]# chkconfig --add mysqld

[root@node1 ~]# chkconfig mysqld on

七、登陆测试

[root@node1 bin]# mysql -uroot -pPassword123

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (111)

解决:

创建软链接:ln -s /data/mysql/tmp/mysql.sock /tmp/mysql.sock

[root@node1 ~]# mysql -uroot -pPassword123
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 8.0.34 MySQL Community Server - GPL

Copyright © 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

root@db 02:59: [(none)]>

#赋予远程访问权限

select host, user, authentication_string, plugin from mysql.user;

update mysql.user set host=’%’ where user=‘root’;

grant all privileges on . to root@’%’ with grant option;

mysql> select host, user, authentication_string, plugin from mysql.user;

±----------±--------------±------------------------------------------±----------------------+

| host | user | authentication_string | plugin |

±----------±--------------±------------------------------------------±----------------------+

| node1 | root | *8232A1298A49F710DBEE0B330C42EEC825D4190A | mysql_native_password |

| node1 | mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password |

| node1 | mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password |

±----------±--------------±------------------------------------------±----------------------+

3 rows in set (0.00 sec)

mysql> update mysql.user set host=’%’ where user=‘root’;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1 Changed: 1 Warnings: 0

mysql> grant all privileges on . to root@’%’ with grant option;

Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;

Query OK, 0 rows affected (0.01 sec)

#刷新权限

flush privileges;

#远程登陆测试

mysql -uroot -pPassword123 -h192.168.100.66 -P3306

[root@node1 local]# mysql -uroot -pPassword123 -h192.168.100.66 -P3306
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 30
Server version: 8.0.34 MySQL Community Server - GPL

Copyright © 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

root@db 04:50: [(none)]>

二.创建测试数据

1.测试数据下载地址:https://github.com/datacharmer/test_db

2.Download ZIP包 test_db-master.zip,并上传到服务器中

或者使用命令下载到本地服务器上
git clone https://github.com/datacharmer/test_db.git

3.解压
unzip test_db-master.zip

4.执行导入命令
mysql -uroot -pPassword123 < employees.sql
mysql -uroot -pPassword123 < employees_partitioned.sql
mysql -uroot -pPassword123 -t < test_employees_md5.sql

[root@node1 test_db-master]# mysql -uroot -pPassword123 -t < test_employees_md5.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
±---------------------+
| INFO |
±---------------------+
| TESTING INSTALLATION |
±---------------------+
±-------------±-----------------±---------------------------------+
| table_name | expected_records | expected_crc |
±-------------±-----------------±---------------------------------+
| departments | 9 | d1af5e170d2d1591d776d5638d71fc5f |
| dept_emp | 331603 | ccf6fe516f990bdaa49713fc478701b7 |
| dept_manager | 24 | 8720e2f0853ac9096b689c14664f847e |
| employees | 300024 | 4ec56ab5ba37218d187cf6ab09ce1aa1 |
| salaries | 2844047 | fd220654e95aea1b169624ffe3fca934 |
| titles | 443308 | bfa016c472df68e70a03facafa1bc0a8 |
±-------------±-----------------±---------------------------------+
±-------------±-----------------±---------------------------------+
| table_name | found_records | found_crc |
±-------------±-----------------±---------------------------------+
| departments | 9 | d1af5e170d2d1591d776d5638d71fc5f |
| dept_emp | 331603 | ccf6fe516f990bdaa49713fc478701b7 |
| dept_manager | 24 | 8720e2f0853ac9096b689c14664f847e |
| employees | 300024 | 4ec56ab5ba37218d187cf6ab09ce1aa1 |
| salaries | 2844047 | fd220654e95aea1b169624ffe3fca934 |
| titles | 443308 | bfa016c472df68e70a03facafa1bc0a8 |
±-------------±-----------------±---------------------------------+
±-------------±--------------±----------+
| table_name | records_match | crc_match |
±-------------±--------------±----------+
| departments | OK | ok |
| dept_emp | OK | ok |
| dept_manager | OK | ok |
| employees | OK | ok |
| salaries | OK | ok |
| titles | OK | ok |
±-------------±--------------±----------+
±-----------------+
| computation_time |
±-----------------+
| 00:00:48 |
±-----------------+
±--------±-------+
| summary | result |
±--------±-------+
| CRC | OK |
| count | OK |
±--------±-------+

到此,Mysql8.0安装与创建测试数据已经完成

三.窗口函数的用法举例

窗口函数是一种强大的数据分析工具,允许在数据集的特定"窗口"(数据子集)内执行计算,同时保留原始行数据。以下是其核心使用方法和场景总结:

一、窗口函数分类及常用函数
序号函数:

ROW_NUMBER():生成连续唯一序号(无并列),如1,2,3。
SELECT name, score, ROW_NUMBER() OVER (ORDER BY score DESC) AS rank FROM students;

RANK():允许并列但序号跳跃(如1,1,3)。

DENSE_RANK():允许并列且序号连续(如1,1,2)。
分布函数:

PERCENT_RANK():计算百分比排名(范围[0,1])。
CUME_DIST():计算累积分布值(如小于等于当前值的行占比)。
前后函数:

LAG(expr, N):获取当前行前第 N 行的值。
LEAD(expr, N):获取当前行后第 N 行的值。
SELECT order_date, LAG(amount, 1) OVER (ORDER BY date) AS prev_amount FROM orders;

二、基本语法结构
函数名([参数]) OVER (
[PARTITION BY 分组字段]
[ORDER BY 排序字段]
[ROWS/RANGE 窗口范围]
)
PARTITION BY:按字段分组,窗口函数在组内独立计算(类似GROUP BY,但保留所有行)。
ORDER BY:定义窗口内的排序规则。
窗口范围:
ROWS:基于物理行数(如ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING包含前一行、当前行、后一行)。
RANGE:基于逻辑值范围(如按时间差值动态扩展窗口)。

实验部分:基于员工部门表dept_emp,以及薪水表salaries进行测试

//UNBOUNDED PRECEDING表示边界永远为第一行:基于第一行进行累加
SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
ROW_NUMBER() OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary DESC) AS row_num,
DENSE_RANK() OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary DESC) AS dept_rank,
SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary ROWS UNBOUNDED PRECEDING) AS salary_total
FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;

root@db 02:28: [employees]> SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
-> ROW_NUMBER() OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary DESC) AS row_num,
-> DENSE_RANK() OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary DESC) AS dept_rank,
-> SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary ROWS UNBOUNDED PRECEDING) AS salary_total
-> FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;
±-------±--------±-------±--------±----------±-------------+
| emp_no | dept_no | salary | row_num | dept_rank | salary_total |
±-------±--------±-------±--------±----------±-------------+
| 10001 | d005 | 60117 | 10 | 10 | 60117 |
| 10001 | d005 | 62102 | 9 | 9 | 122219 |
| 10001 | d005 | 66074 | 8 | 8 | 188293 |
| 10001 | d005 | 66596 | 7 | 7 | 254889 |
| 10001 | d005 | 66961 | 6 | 6 | 321850 |
| 10001 | d005 | 71046 | 5 | 5 | 392896 |
| 10001 | d005 | 74333 | 4 | 4 | 467229 |
| 10001 | d005 | 75286 | 3 | 3 | 542515 |
| 10001 | d005 | 75994 | 2 | 2 | 618509 |
| 10001 | d005 | 76884 | 1 | 1 | 695393 |
±-------±--------±-------±--------±----------±-------------+
10 rows in set (0.00 sec)

//CURRENT ROW表示获取当前行记录,也就是边界是当前行,等值关系
SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
ROW_NUMBER() OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary DESC) AS row_num,
DENSE_RANK() OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary DESC) AS dept_rank,
SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary range current row) AS salary_total
FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;

root@db 02:28: [employees]> SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
-> ROW_NUMBER() OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary DESC) AS row_num,
-> DENSE_RANK() OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary DESC) AS dept_rank,
-> SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary range current row) AS salary_total
-> FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;
±-------±--------±-------±--------±----------±-------------+
| emp_no | dept_no | salary | row_num | dept_rank | salary_total |
±-------±--------±-------±--------±----------±-------------+
| 10001 | d005 | 60117 | 10 | 10 | 60117 |
| 10001 | d005 | 62102 | 9 | 9 | 62102 |
| 10001 | d005 | 66074 | 8 | 8 | 66074 |
| 10001 | d005 | 66596 | 7 | 7 | 66596 |
| 10001 | d005 | 66961 | 6 | 6 | 66961 |
| 10001 | d005 | 71046 | 5 | 5 | 71046 |
| 10001 | d005 | 74333 | 4 | 4 | 74333 |
| 10001 | d005 | 75286 | 3 | 3 | 75286 |
| 10001 | d005 | 75994 | 2 | 2 | 75994 |
| 10001 | d005 | 76884 | 1 | 1 | 76884 |
±-------±--------±-------±--------±----------±-------------+
10 rows in set (0.01 sec)

//UNBOUNDED FOLLOWING 表示边界永远为最后一行
SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
ROW_NUMBER() OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary DESC) AS row_num,
DENSE_RANK() OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary DESC) AS dept_rank,
SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary ROWS BETWEEN UNBOUNDED preceding and UNBOUNDED FOLLOWING) AS salary_total
FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;

root@db 02:39: [employees]> SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
-> ROW_NUMBER() OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary DESC) AS row_num,
-> DENSE_RANK() OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary DESC) AS dept_rank,
-> SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary ROWS BETWEEN UNBOUNDED preceding and UNBOUNDED FOLLOWING) AS salary_total
-> FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;
±-------±--------±-------±--------±----------±-------------+
| emp_no | dept_no | salary | row_num | dept_rank | salary_total |
±-------±--------±-------±--------±----------±-------------+
| 10001 | d005 | 60117 | 10 | 10 | 695393 |
| 10001 | d005 | 62102 | 9 | 9 | 695393 |
| 10001 | d005 | 66074 | 8 | 8 | 695393 |
| 10001 | d005 | 66596 | 7 | 7 | 695393 |
| 10001 | d005 | 66961 | 6 | 6 | 695393 |
| 10001 | d005 | 71046 | 5 | 5 | 695393 |
| 10001 | d005 | 74333 | 4 | 4 | 695393 |
| 10001 | d005 | 75286 | 3 | 3 | 695393 |
| 10001 | d005 | 75994 | 2 | 2 | 695393 |
| 10001 | d005 | 76884 | 1 | 1 | 695393 |
±-------±--------±-------±--------±----------±-------------+
10 rows in set (0.00 sec)

//EXPR PRECEDING/FOLLOWING 表示带表达式的边界。

SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary ROWS 1 PRECEDING) AS salary_total
FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;

root@db 01:55: [employees]> select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10
-> ;
±-------±--------±-------+
| emp_no | dept_no | salary |
±-------±--------±-------+
| 10001 | d005 | 60117 |
| 10001 | d005 | 62102 |
| 10001 | d005 | 66074 |
| 10001 | d005 | 66596 |
| 10001 | d005 | 66961 |
| 10001 | d005 | 71046 |
| 10001 | d005 | 74333 |
| 10001 | d005 | 75286 |
| 10001 | d005 | 75994 |
| 10001 | d005 | 76884 |
±-------±--------±-------+
10 rows in set (0.01 sec)

root@db 01:55: [employees]> SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
-> SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary ROWS 1 PRECEDING) AS salary_total
-> FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;
±-------±--------±-------±-------------+
| emp_no | dept_no | salary | salary_total |
±-------±--------±-------±-------------+
| 10001 | d005 | 60117 | 60117 |
| 10001 | d005 | 62102 | 122219 |
| 10001 | d005 | 66074 | 128176 |
| 10001 | d005 | 66596 | 132670 |
| 10001 | d005 | 66961 | 133557 |
| 10001 | d005 | 71046 | 138007 |
| 10001 | d005 | 74333 | 145379 |
| 10001 | d005 | 75286 | 149619 |
| 10001 | d005 | 75994 | 151280 |
| 10001 | d005 | 76884 | 152878 |
±-------±--------±-------±-------------+
10 rows in set (0.36 sec)

上面的查询表达的意思是基于分组内每行记录和它上一条记录求和,不累加。

//求每行和它上面两行的和:

SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary ROWS 2 PRECEDING) AS salary_total
FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;

root@db 01:57: [employees]> SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
-> SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary ROWS 2 PRECEDING) AS salary_total
-> FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;
±-------±--------±-------±-------------+
| emp_no | dept_no | salary | salary_total |
±-------±--------±-------±-------------+
| 10001 | d005 | 60117 | 60117 |
| 10001 | d005 | 62102 | 122219 |
| 10001 | d005 | 66074 | 188293 |
| 10001 | d005 | 66596 | 194772 |
| 10001 | d005 | 66961 | 199631 |
| 10001 | d005 | 71046 | 204603 |
| 10001 | d005 | 74333 | 212340 |
| 10001 | d005 | 75286 | 220665 |
| 10001 | d005 | 75994 | 225613 |
| 10001 | d005 | 76884 | 228164 |
±-------±--------±-------±-------------+
10 rows in set (0.00 sec)

//求每行的前两行和后面四行相加的结果

SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary ROWS between 2 PRECEDING and 4 FOLLOWING) AS salary_total
FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;

root@db 02:00: [employees]> SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
-> SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary ROWS between 2 PRECEDING and 4 FOLLOWING) AS salary_total
-> FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;
±-------±--------±-------±-------------+
| emp_no | dept_no | salary | salary_total |
±-------±--------±-------±-------------+
| 10001 | d005 | 60117 | 321850 |
| 10001 | d005 | 62102 | 392896 |
| 10001 | d005 | 66074 | 467229 |
| 10001 | d005 | 66596 | 482398 |
| 10001 | d005 | 66961 | 496290 |
| 10001 | d005 | 71046 | 507100 |
| 10001 | d005 | 74333 | 440504 |
| 10001 | d005 | 75286 | 373543 |
| 10001 | d005 | 75994 | 302497 |
| 10001 | d005 | 76884 | 228164 |
±-------±--------±-------±-------------+
10 rows in set (0.00 sec)

RANGE PRECEDING/FOLLOWING
表示当前行值范围内的分组记录。ROWS对应的是行号,RANGE对应的行值。

计算逻辑是:计算当前行salary减去1的值,如果计算的值在结果集中不存在,此时salary_total的值为salary当前值,如果计算的值在结果集中存在,此时salary_total的值为salary当前值加上【salary的值减去1】。

SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary RANGE 1 PRECEDING) AS salary_total
FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;

root@db 02:13: [employees]> SELECT tmp.emp_no,tmp.dept_no, tmp.salary, SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary RANGE 1 PRECEDING) AS salary_total FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;
±-------±--------±-------±-------------+
| emp_no | dept_no | salary | salary_total |
±-------±--------±-------±-------------+
| 10001 | d005 | 60117 | 60117 |
| 10001 | d005 | 62102 | 62102 |
| 10001 | d005 | 66074 | 66074 |
| 10001 | d005 | 66596 | 66596 |
| 10001 | d005 | 66961 | 66961 |
| 10001 | d005 | 71046 | 71046 |
| 10001 | d005 | 74333 | 74333 |
| 10001 | d005 | 75286 | 75286 |
| 10001 | d005 | 75994 | 75994 |
| 10001 | d005 | 76884 | 76884 |
±-------±--------±-------±-------------+
10 rows in set (0.00 sec)

//RANGE between 1 PRECEDING and 1 FOLLOWING:对每行值-1和+1后对应的值进行求和
计算逻辑:计算当前行值-1和+1后对应的值,如果在结果集中都不存在,则salary_total的值取salary的当前值;
如果在结果集中存在,则salary_total的值取salary的当前值+对应的值。

SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary RANGE between 1 PRECEDING and 1 FOLLOWING ) AS salary_total
FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;

root@db 02:13: [employees]> SELECT tmp.emp_no,tmp.dept_no, tmp.salary,
-> SUM(tmp.salary) OVER (PARTITION BY tmp.dept_no ORDER BY tmp.salary RANGE between 1 PRECEDING and 1 FOLLOWING ) AS salary_total
-> FROM (select de.emp_no,de.dept_no,sa.salary from dept_emp de, salaries sa where de.emp_no=sa.emp_no and dept_no=‘d005’ limit 10) tmp;
±-------±--------±-------±-------------+
| emp_no | dept_no | salary | salary_total |
±-------±--------±-------±-------------+
| 10001 | d005 | 60117 | 60117 |
| 10001 | d005 | 62102 | 62102 |
| 10001 | d005 | 66074 | 66074 |
| 10001 | d005 | 66596 | 66596 |
| 10001 | d005 | 66961 | 66961 |
| 10001 | d005 | 71046 | 71046 |
| 10001 | d005 | 74333 | 74333 |
| 10001 | d005 | 75286 | 75286 |
| 10001 | d005 | 75994 | 75994 |
| 10001 | d005 | 76884 | 76884 |
±-------±--------±-------±-------------+
10 rows in set (0.00 sec)

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论