mysql 分析函数_MySQL实现常用分析函数

分别在 MySQL5.7.25-log 和 8.0.16 环境中实现类似Oracle的分析函数(8.0版本中已支持,直接使用即可)。

一、创建测试数据

二、row_number() over()

三、rank() over()

四、dense_rank() over()

五、lag() over()

六、lead() over()

七、待补充

一、创建测试数据:

CREATE TABLE `devicecounter` (

`roomid` int(11) DEFAULT NULL,

`deviceid` int(11) DEFAULT NULL,

`counter` decimal(12,4) DEFAULT NULL,

`readtime` datetime DEFAULT NULL

) ENGINE=InnoDB;

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (536, 147, 26.0000, '2020-01-17 10:21:16');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (536, 502, 872.2700, '2020-01-17 10:21:19');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (3750, 4922, 1304.8000, '2020-01-17 10:21:30');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (3750, 5164, 20.9450, '2020-01-17 10:21:36');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (3928, 6282, 2514.7000, '2020-01-17 10:21:40');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (3930, 6284, 2087.8300, '2020-01-17 10:42:11');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (3930, 6284, 2087.7300, '2020-01-17 10:41:08');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (3928, 6434, 70.0000, '2020-01-17 10:21:42');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (3930, 6436, 18.5000, '2020-01-17 10:45:11');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (3930, 6436, 18.0000, '2020-01-17 10:41:10');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (3981, 7260, 5.6000, '2020-01-17 10:21:38');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (4038, 7314, 6.6000, '2020-01-17 10:25:31');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (4038, 7314, 5.8000, '2020-01-17 10:19:30');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (3981, 7364, 838.7000, '2020-01-17 10:21:33');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (4038, 7418, 253.5000, '2020-01-17 10:30:31');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (4038, 7418, 252.7000, '2020-01-17 10:19:29');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (3981, 7468, 12.0000, '2020-01-17 10:21:29');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (4038, 7522, 12.8000, '2020-01-17 10:29:31');

INSERT INTO `devicecounter`(`roomid`, `deviceid`, `counter`, `readtime`) VALUES (4038, 7522, 12.0000, '2020-01-17 10:19:30');

二、查询结果添加序列号,类Oracle 的row_number() OVER()

例1:不分组,全部数据添加序列号,类Oracle 的rownum伪列

#### 按照房间和设备排序,依次标注序列号

######### MySQL5.7

mysql> SELECT

( @rownum := @rownum + 1 ) AS rownum,

a.*

FROM

devicecounter a,

( SELECT @rownum := 0 ) AS t

ORDER BY roomid,deviceid,counter;

+--------+--------+----------+-----------+---------------------+

| rownum | roomid | deviceid | counter | readtime |

+--------+--------+----------+-----------+---------------------+

| 1 | 536 | 147 | 26.0000 | 2020-01-17 10:21:16 |

| 2 | 536 | 502 | 872.2700 | 2020-01-17 10:21:19 |

| 3 | 3750 | 4922 | 1304.8000 | 2020-01-17 10:21:30 |

| 4 | 3750 | 5164 | 20.9450 | 2020-01-17 10:21:36 |

| 5 | 3928 | 6282 | 2514.7000 | 2020-01-17 10:21:40 |

| 6 | 3928 | 6434 | 70.0000 | 2020-01-17 10:21:42 |

| 7 | 3930 | 6284 | 2087.7300 | 2020-01-17 10:41:08 |

| 8 | 3930 | 6284 | 2087.8300 | 2020-01-17 10:42:11 |

| 9 | 3930 | 6436 | 18.0000 | 2020-01-17 10:41:10 |

| 10 | 3930 | 6436 | 18.5000 | 2020-01-17 10:45:11 |

| 11 | 3981 | 7260 | 5.6000 | 2020-01-17 10:21:38 |

| 12 | 3981 | 7364 | 838.7000 | 2020-01-17 10:21:33 |

| 13 | 3981 | 7468 | 12.0000 | 2020-01-17 10:21:29 |

| 14 | 4038 | 7314 | 5.8000 | 2020-01-17 10:19:30 |

| 15 | 4038 | 7314 | 6.6000 | 2020-01-17 10:25:31 |

| 16 | 4038 | 7418 | 252.7000 | 2020-01-17 10:19:29 |

| 17 | 4038 | 7418 | 253.5000 | 2020-01-17 10:30:31 |

| 18 | 4038 | 7522 | 12.0000 | 2020-01-17 10:19:30 |

| 19 | 4038 | 7522 | 12.8000 | 2020-01-17 10:29:31 |

+--------+--------+----------+-----------+---------------------+

######### MySQL8.0

mysql>SELECT

ROW_NUMBER () OVER w AS 'row_number',

a.*

FROM devicecounter a

WINDOW w AS ( ORDER BY roomid,deviceid,counter );

#或者下面写法:

SELECT

ROW_NUMBER() OVER (ORDER BY roomid,deviceid,counter) AS 'row_number',

a.*

FROM devicecounter a;

查询结果同上,不予列出。

例2:先按roomid分组,再按照deviceid,counter排序,类Oracle 的row_number() OVER(PARTITION BY ORDER BY )

##### 先按照房间分组,再添加序列号

######### MySQL5.7

mysql> SELECT

a.*,

IF( @room_id = roomid,@rownum := @rownum + 1, @rownum := 1 ) AS rownum,

@room_id := roomid AS roomid1

FROM

devicecounter a,(SELECT @rownum := 0, @room_id := 0) AS t

ORDER BY roomid,deviceid,counter;

+--------+----------+-----------+---------------------+--------+---------+

| roomid | deviceid | counter | readtime | rownum | roomid1 |

+--------+----------+-----------+---------------------+--------+---------+

| 536 | 147 | 26.0000 | 2020-01-17 10:21:16 | 1 | 536 |

| 536 | 502 | 872.2700 | 2020-01-17 10:21:19 | 2 | 536 |

| 3750 | 4922 | 1304.8000 | 2020-01-17 10:21:30 | 1 | 3750 |

| 3750 | 5164 | 20.9450 | 2020-01-17 10:21:36 | 2 | 3750 |

| 3928 | 6282 | 2514.7000 | 2020-01-17 10:21:40 | 1 | 3928 |

| 3928 | 6434 | 70.0000 | 2020-01-17 10:21:42 | 2 | 3928 |

| 3930 | 6284 | 2087.7300 | 2020-01-17 10:41:08 | 1 | 3930 |

| 3930 | 6284 | 2087.8300 | 2020-01-17 10:42:11 | 2 | 3930 |

| 3930 | 6436 | 18.0000 | 2020-01-17 10:41:10 | 3 | 3930 |

| 3930 | 6436 | 18.5000 | 2020-01-17 10:45:11 | 4 | 3930 |

| 3981 | 7260 | 5.6000 | 2020-01-17 10:21:38 | 1 | 3981 |

| 3981 | 7364 | 838.7000 | 2020-01-17 10:21:33 | 2 | 3981 |

| 3981 | 7468 | 12.0000 | 2020-01-17 10:21:29 | 3 | 3981 |

| 4038 | 7314 | 5.8000 | 2020-01-17 10:19:30 | 1 | 4038 |

| 4038 | 7314 | 6.6000 | 2020-01-17 10:25:31 | 2 | 4038 |

| 4038 | 7418 | 252.7000 | 2020-01-17 10:19:29 | 3 | 4038 |

| 4038 | 7418 | 253.5000 | 2020-01-17 10:30:31 | 4 | 4038 |

| 4038 | 7522 | 12.0000 | 2020-01-17 10:19:30 | 5 | 4038 |

| 4038 | 7522 | 12.8000 | 2020-01-17 10:29:31 | 6 | 4038 |

+--------+----------+-----------+---------------------+--------+---------+

######### MySQL8.0

mysql>SELECT

a.*,

ROW_NUMBER() OVER w AS 'row_number'

FROM devicecounter a

WINDOW w AS ( PARTITION BY roomid order by deviceid,counter);

#或者下面写法:

SELECT

a.*,

ROW_NUMBER() OVER (PARTITION BY roomid order by deviceid,counter) AS 'row_number'

FROM devicecounter a;

三、rank,类似Oracle的 rank() over()

例1:不分组,全部数据按 roomid 排序,再添加序号,类Oracle 的rank() OVER(ORDER BY)

######### MySQL5.7

mysql> SELECT

a.*,

@rownum := @rownum + 1 AS rownum,

IF(@room_id = roomid, @rank := @rank,@rank := @rownum) AS rank,

@room_id := roomid AS roomid1

FROM

devicecounter a,(SELECT @rownum := 0, @rank := 0,@room_id:= 0) AS t

ORDER BY roomid;

+--------+----------+-----------+---------------------+--------+------+---------+

| roomid | deviceid | counter | readtime | rownum | rank | roomid1 |

+--------+----------+-----------+---------------------+--------+------+---------+

| 536 | 502 | 872.2700 | 2020-01-17 10:21:19 | 1 | 1 | 536 |

| 536 | 147 | 26.0000 | 2020-01-17 10:21:16 | 2 | 1 | 536 |

| 3750 | 5164 | 20.9450 | 2020-01-17 10:21:36 | 3 | 3 | 3750 |

| 3750 | 4922 | 1304.8000 | 2020-01-17 10:21:30 | 4 | 3 | 3750 |

| 3928 | 6434 | 70.0000 | 2020-01-17 10:21:42 | 5 | 5 | 3928 |

| 3928 | 6282 | 2514.7000 | 2020-01-17 10:21:40 | 6 | 5 | 3928 |

| 3930 | 6284 | 2087.8300 | 2020-01-17 10:42:11 | 7 | 7 | 3930 |

| 3930 | 6436 | 18.5000 | 2020-01-17 10:45:11 | 8 | 7 | 3930 |

| 3930 | 6436 | 18.0000 | 2020-01-17 10:41:10 | 9 | 7 | 3930 |

| 3930 | 6284 | 2087.7300 | 2020-01-17 10:41:08 | 10 | 7 | 3930 |

| 3981 | 7260 | 5.6000 | 2020-01-17 10:21:38 | 11 | 11 | 3981 |

| 3981 | 7364 | 838.7000 | 2020-01-17 10:21:33 | 12 | 11 | 3981 |

| 3981 | 7468 | 12.0000 | 2020-01-17 10:21:29 | 13 | 11 | 3981 |

| 4038 | 7418 | 253.5000 | 2020-01-17 10:30:31 | 14 | 14 | 4038 |

| 4038 | 7314 | 6.6000 | 2020-01-17 10:25:31 | 15 | 14 | 4038 |

| 4038 | 7522 | 12.8000 | 2020-01-17 10:29:31 | 16 | 14 | 4038 |

| 4038 | 7522 | 12.0000 | 2020-01-17 10:19:30 | 17 | 14 | 4038 |

| 4038 | 7314 | 5.8000 | 2020-01-17 10:19:30 | 18 | 14 | 4038 |

| 4038 | 7418 | 252.7000 | 2020-01-17 10:19:29 | 19 | 14 | 4038 |

+--------+----------+-----------+---------------------+--------+------+---------+

######### MySQL8.0

mysql> SELECT

a.*,

rank() OVER w AS 'rank'

FROM devicecounter a

WINDOW w AS (order by roomid) ;

#或者下面写法:

SELECT

a.*,

rank() OVER (order by roomid) AS 'rank'

FROM devicecounter a ;

例2:先按roomid分组,再按deviceid排序,类Oracle 的rank() OVER(PARTITION BY ORDER BY)

######### MySQL5.7

mysql> SELECT

a.*,

IF(@room_id = roomid, @rownum := @rownum + 1, @rownum := 1 ) AS rownum,

IF(@device_id = deviceid, @rank := @rank,@rank := @rownum) AS rank ,

@device_id := deviceid AS deviceid1,

@room_id := roomid AS roomid1

FROM

devicecounter a,(SELECT @rownum := 0, @room_id := -1, @rank := 0,@device_id:= -1) AS t

ORDER BY roomid,deviceid;

+--------+----------+-----------+---------------------+--------+------+-----------+---------+

| roomid | deviceid | counter | readtime | rownum | rank | deviceid1 | roomid1 |

+--------+----------+-----------+---------------------+--------+------+-----------+---------+

| 536 | 147 | 26.0000 | 2020-01-17 10:21:16 | 1 | 1 | 147 | 536 |

| 536 | 502 | 872.2700 | 2020-01-17 10:21:19 | 2 | 2 | 502 | 536 |

| 3750 | 4922 | 1304.8000 | 2020-01-17 10:21:30 | 1 | 1 | 4922 | 3750 |

| 3750 | 5164 | 20.9450 | 2020-01-17 10:21:36 | 2 | 2 | 5164 | 3750 |

| 3928 | 6282 | 2514.7000 | 2020-01-17 10:21:40 | 1 | 1 | 6282 | 3928 |

| 3928 | 6434 | 70.0000 | 2020-01-17 10:21:42 | 2 | 2 | 6434 | 3928 |

| 3930 | 6284 | 2087.8300 | 2020-01-17 10:42:11 | 1 | 1 | 6284 | 3930 |

| 3930 | 6284 | 2087.7300 | 2020-01-17 10:41:08 | 2 | 1 | 6284 | 3930 |

| 3930 | 6436 | 18.5000 | 2020-01-17 10:45:11 | 3 | 3 | 6436 | 3930 |

| 3930 | 6436 | 18.0000 | 2020-01-17 10:41:10 | 4 | 3 | 6436 | 3930 |

| 3981 | 7260 | 5.6000 | 2020-01-17 10:21:38 | 1 | 1 | 7260 | 3981 |

| 3981 | 7364 | 838.7000 | 2020-01-17 10:21:33 | 2 | 2 | 7364 | 3981 |

| 3981 | 7468 | 12.0000 | 2020-01-17 10:21:29 | 3 | 3 | 7468 | 3981 |

| 4038 | 7314 | 6.6000 | 2020-01-17 10:25:31 | 1 | 1 | 7314 | 4038 |

| 4038 | 7314 | 5.8000 | 2020-01-17 10:19:30 | 2 | 1 | 7314 | 4038 |

| 4038 | 7418 | 253.5000 | 2020-01-17 10:30:31 | 3 | 3 | 7418 | 4038 |

| 4038 | 7418 | 252.7000 | 2020-01-17 10:19:29 | 4 | 3 | 7418 | 4038 |

| 4038 | 7522 | 12.8000 | 2020-01-17 10:29:31 | 5 | 5 | 7522 | 4038 |

| 4038 | 7522 | 12.0000 | 2020-01-17 10:19:30 | 6 | 5 | 7522 | 4038 |

+--------+----------+-----------+---------------------+--------+------+-----------+---------+

######### MySQL8.0

mysql>SELECT

a.*,

rank() OVER w AS 'rank'

FROM devicecounter a

WINDOW w AS (PARTITION BY roomid order by deviceid);

#或者下面写法:

mysql>SELECT

a.*,

rank() OVER (PARTITION BY roomid order by deviceidq) AS 'rank'

FROM devicecounter a ;

四、dense_rank,类Oracle 的 dense_rank() over()

例1:不分组,全部数据按roomid排序,再添加序号,类Oracle 的dense_rank() OVER(ORDER BY)

######### MySQL5.7

mysql> SELECT

a.*,

@rank := @rank + if(@room_id = roomid,0,1) AS rank ,

@room_id := roomid AS roomid1

FROM

devicecounter a,(SELECT @room_id := -1, @rank := 0,@device_id:= -1) AS t

ORDER BY roomid,deviceid;

+--------+----------+-----------+---------------------+------+---------+

| roomid | deviceid | counter | readtime | rank | roomid1 |

+--------+----------+-----------+---------------------+------+---------+

| 536 | 147 | 26.0000 | 2020-01-17 10:21:16 | 1 | 536 |

| 536 | 502 | 872.2700 | 2020-01-17 10:21:19 | 1 | 536 |

| 3750 | 4922 | 1304.8000 | 2020-01-17 10:21:30 | 2 | 3750 |

| 3750 | 5164 | 20.9450 | 2020-01-17 10:21:36 | 2 | 3750 |

| 3928 | 6282 | 2514.7000 | 2020-01-17 10:21:40 | 3 | 3928 |

| 3928 | 6434 | 70.0000 | 2020-01-17 10:21:42 | 3 | 3928 |

| 3930 | 6284 | 2087.8300 | 2020-01-17 10:42:11 | 4 | 3930 |

| 3930 | 6284 | 2087.7300 | 2020-01-17 10:41:08 | 4 | 3930 |

| 3930 | 6436 | 18.5000 | 2020-01-17 10:45:11 | 4 | 3930 |

| 3930 | 6436 | 18.0000 | 2020-01-17 10:41:10 | 4 | 3930 |

| 3981 | 7260 | 5.6000 | 2020-01-17 10:21:38 | 5 | 3981 |

| 3981 | 7364 | 838.7000 | 2020-01-17 10:21:33 | 5 | 3981 |

| 3981 | 7468 | 12.0000 | 2020-01-17 10:21:29 | 5 | 3981 |

| 4038 | 7314 | 6.6000 | 2020-01-17 10:25:31 | 6 | 4038 |

| 4038 | 7314 | 5.8000 | 2020-01-17 10:19:30 | 6 | 4038 |

| 4038 | 7418 | 253.5000 | 2020-01-17 10:30:31 | 6 | 4038 |

| 4038 | 7418 | 252.7000 | 2020-01-17 10:19:29 | 6 | 4038 |

| 4038 | 7522 | 12.8000 | 2020-01-17 10:29:31 | 6 | 4038 |

| 4038 | 7522 | 12.0000 | 2020-01-17 10:19:30 | 6 | 4038 |

+--------+----------+-----------+---------------------+------+---------+

######### MySQL8.0

mysql>mysql>SELECT

a.*,

dense_rank() OVER w AS 'dense_rank'

FROM devicecounter a

WINDOW w AS (order by roomid);

#或者下面写法:

mysql>SELECT

a.*,

dense_rank() OVER (order by roomid) AS 'dense_rank'

FROM devicecounter a ;

例2:先按roomid分组,再按deviceid排序,类Oracle 的dense_rank() OVER(PARTITION BY ORDER BY)

######### MySQL5.7

mysql> SELECT

a.*,

IF(@room_id = roomid, @rank := @rank + if(@device_id = deviceid,0,1),@rank := 1) AS dense_rank ,

@device_id := deviceid AS deviceid1,

@room_id := roomid AS roomid1

FROM

devicecounter a,(SELECT @room_id := -1, @rank := 0,@device_id:= -1) AS t

ORDER BY roomid,deviceid;

+--------+----------+-----------+---------------------+------------+-----------+---------+

| roomid | deviceid | counter | readtime | dense_rank | deviceid1 | roomid1 |

+--------+----------+-----------+---------------------+------------+-----------+---------+

| 536 | 147 | 26.0000 | 2020-01-17 10:21:16 | 1 | 147 | 536 |

| 536 | 502 | 872.2700 | 2020-01-17 10:21:19 | 2 | 502 | 536 |

| 3750 | 4922 | 1304.8000 | 2020-01-17 10:21:30 | 1 | 4922 | 3750 |

| 3750 | 5164 | 20.9450 | 2020-01-17 10:21:36 | 2 | 5164 | 3750 |

| 3928 | 6282 | 2514.7000 | 2020-01-17 10:21:40 | 1 | 6282 | 3928 |

| 3928 | 6434 | 70.0000 | 2020-01-17 10:21:42 | 2 | 6434 | 3928 |

| 3930 | 6284 | 2087.8300 | 2020-01-17 10:42:11 | 1 | 6284 | 3930 |

| 3930 | 6284 | 2087.7300 | 2020-01-17 10:41:08 | 1 | 6284 | 3930 |

| 3930 | 6436 | 18.5000 | 2020-01-17 10:45:11 | 2 | 6436 | 3930 |

| 3930 | 6436 | 18.0000 | 2020-01-17 10:41:10 | 2 | 6436 | 3930 |

| 3981 | 7260 | 5.6000 | 2020-01-17 10:21:38 | 1 | 7260 | 3981 |

| 3981 | 7364 | 838.7000 | 2020-01-17 10:21:33 | 2 | 7364 | 3981 |

| 3981 | 7468 | 12.0000 | 2020-01-17 10:21:29 | 3 | 7468 | 3981 |

| 4038 | 7314 | 6.6000 | 2020-01-17 10:25:31 | 1 | 7314 | 4038 |

| 4038 | 7314 | 5.8000 | 2020-01-17 10:19:30 | 1 | 7314 | 4038 |

| 4038 | 7418 | 253.5000 | 2020-01-17 10:30:31 | 2 | 7418 | 4038 |

| 4038 | 7418 | 252.7000 | 2020-01-17 10:19:29 | 2 | 7418 | 4038 |

| 4038 | 7522 | 12.8000 | 2020-01-17 10:29:31 | 3 | 7522 | 4038 |

| 4038 | 7522 | 12.0000 | 2020-01-17 10:19:30 | 3 | 7522 | 4038 |

+--------+----------+-----------+---------------------+------------+-----------+---------+

######### MySQL8.0

mysql>SELECT

a.*,

dense_rank() OVER w AS 'dense_rank'

FROM devicecounter a

WINDOW w AS (PARTITION BY roomid order by deviceid);

#或者下面写法:

mysql> SELECT

a.*,

dense_rank() OVER (PARTITION BY roomid order by deviceid) AS 'dense_rank'

FROM devicecounter a ;

五、lag,类Oracle 的 lag() over()

例1:不分组,全部数据按roomid,deviceid升序排序,类Oracle 的lag() OVER(ORDER BY)

######### MySQL5.7

mysql> SELECT

a.*,

@lag as lag_field,

@lag:=deviceid

FROM

devicecounter a,(SELECT @lag := '') AS t

ORDER BY roomid,deviceid;

+--------+----------+-----------+---------------------+-----------+----------------+

| roomid | deviceid | counter | readtime | lag_field | @lag:=deviceid |

+--------+----------+-----------+---------------------+-----------+----------------+

| 536 | 147 | 26.0000 | 2020-01-17 10:21:16 | | 147 |

| 536 | 502 | 872.2700 | 2020-01-17 10:21:19 | 147 | 502 |

| 3750 | 4922 | 1304.8000 | 2020-01-17 10:21:30 | 502 | 4922 |

| 3750 | 5164 | 20.9450 | 2020-01-17 10:21:36 | 4922 | 5164 |

| 3928 | 6282 | 2514.7000 | 2020-01-17 10:21:40 | 5164 | 6282 |

| 3928 | 6434 | 70.0000 | 2020-01-17 10:21:42 | 6282 | 6434 |

| 3930 | 6284 | 2087.8300 | 2020-01-17 10:42:11 | 6434 | 6284 |

| 3930 | 6284 | 2087.7300 | 2020-01-17 10:41:08 | 6284 | 6284 |

| 3930 | 6436 | 18.5000 | 2020-01-17 10:45:11 | 6284 | 6436 |

| 3930 | 6436 | 18.0000 | 2020-01-17 10:41:10 | 6436 | 6436 |

| 3981 | 7260 | 5.6000 | 2020-01-17 10:21:38 | 6436 | 7260 |

| 3981 | 7364 | 838.7000 | 2020-01-17 10:21:33 | 7260 | 7364 |

| 3981 | 7468 | 12.0000 | 2020-01-17 10:21:29 | 7364 | 7468 |

| 4038 | 7314 | 6.6000 | 2020-01-17 10:25:31 | 7468 | 7314 |

| 4038 | 7314 | 5.8000 | 2020-01-17 10:19:30 | 7314 | 7314 |

| 4038 | 7418 | 253.5000 | 2020-01-17 10:30:31 | 7314 | 7418 |

| 4038 | 7418 | 252.7000 | 2020-01-17 10:19:29 | 7418 | 7418 |

| 4038 | 7522 | 12.8000 | 2020-01-17 10:29:31 | 7418 | 7522 |

| 4038 | 7522 | 12.0000 | 2020-01-17 10:19:30 | 7522 | 7522 |

+--------+----------+-----------+---------------------+-----------+----------------+

######### MySQL8.0

mysql> SELECT

a.*,

lag(deviceid) over w as lag_field

FROM

devicecounter a

WINDOW w AS (ORDER BY roomid,deviceid);

#或者下面写法:

mysql> SELECT

a.*,

lag(deviceid) over(ORDER BY roomid,deviceid) as lag_field

FROM

devicecounter a ;

例2:先按roomid分组,再按roomid,deviceid排序,类Oracle 的lag() OVER(PARTITION BY ORDER BY)

######### MySQL5.7

mysql> SELECT

a.*,

if(@room_id=roomid,@lag,'') as lag_field,

@lag:=deviceid,

@room_id:=roomid

FROM

devicecounter a,(SELECT @lag := '',@room_id:=-1) AS t

ORDER BY roomid,deviceid;

+--------+----------+-----------+---------------------+-----------+----------------+------------------+

| roomid | deviceid | counter | readtime | lag_field | @lag:=deviceid | @room_id:=roomid |

+--------+----------+-----------+---------------------+-----------+----------------+------------------+

| 536 | 147 | 26.0000 | 2020-01-17 10:21:16 | | 147 | 536 |

| 536 | 502 | 872.2700 | 2020-01-17 10:21:19 | 147 | 502 | 536 |

| 3750 | 4922 | 1304.8000 | 2020-01-17 10:21:30 | | 4922 | 3750 |

| 3750 | 5164 | 20.9450 | 2020-01-17 10:21:36 | 4922 | 5164 | 3750 |

| 3928 | 6282 | 2514.7000 | 2020-01-17 10:21:40 | | 6282 | 3928 |

| 3928 | 6434 | 70.0000 | 2020-01-17 10:21:42 | 6282 | 6434 | 3928 |

| 3930 | 6284 | 2087.8300 | 2020-01-17 10:42:11 | | 6284 | 3930 |

| 3930 | 6284 | 2087.7300 | 2020-01-17 10:41:08 | 6284 | 6284 | 3930 |

| 3930 | 6436 | 18.5000 | 2020-01-17 10:45:11 | 6284 | 6436 | 3930 |

| 3930 | 6436 | 18.0000 | 2020-01-17 10:41:10 | 6436 | 6436 | 3930 |

| 3981 | 7260 | 5.6000 | 2020-01-17 10:21:38 | | 7260 | 3981 |

| 3981 | 7364 | 838.7000 | 2020-01-17 10:21:33 | 7260 | 7364 | 3981 |

| 3981 | 7468 | 12.0000 | 2020-01-17 10:21:29 | 7364 | 7468 | 3981 |

| 4038 | 7314 | 6.6000 | 2020-01-17 10:25:31 | | 7314 | 4038 |

| 4038 | 7314 | 5.8000 | 2020-01-17 10:19:30 | 7314 | 7314 | 4038 |

| 4038 | 7418 | 253.5000 | 2020-01-17 10:30:31 | 7314 | 7418 | 4038 |

| 4038 | 7418 | 252.7000 | 2020-01-17 10:19:29 | 7418 | 7418 | 4038 |

| 4038 | 7522 | 12.8000 | 2020-01-17 10:29:31 | 7418 | 7522 | 4038 |

| 4038 | 7522 | 12.0000 | 2020-01-17 10:19:30 | 7522 | 7522 | 4038 |

+--------+----------+-----------+---------------------+-----------+----------------+------------------+

######### MySQL8.0

mysql> SELECT

a.*,

lag(deviceid) over w as lag_field

FROM

devicecounter a

WINDOW w AS (PARTITION by roomid ORDER BY roomid,deviceid);

#或者下面写法:

mysql> SELECT

a.*,

lag(deviceid) over(PARTITION by roomid ORDER BY roomid,deviceid) as lag_field

FROM

devicecounter a ;

六、lead,类Oracle 的 lead() over()

例1:不分组,全部数据按roomid,deviceid,counter升序排序,类Oracle 的lead() OVER(ORDER BY)

######### MySQL5.7 先全部降序,获取前一个值,然后再升序即可

mysql> select * from (

SELECT

a.*,

@lead as lead_field,

@lead:=deviceid

FROM

devicecounter a,(SELECT @lead := '') AS t

ORDER BY roomid desc ,deviceid desc,counter desc)tt

ORDER BY roomid ,deviceid,counter;

+--------+----------+-----------+---------------------+------------+-----------------+

| roomid | deviceid | counter | readtime | lead_field | @lead:=deviceid |

+--------+----------+-----------+---------------------+------------+-----------------+

| 536 | 147 | 26.0000 | 2020-01-17 10:21:16 | 502 | 147 |

| 536 | 502 | 872.2700 | 2020-01-17 10:21:19 | 4922 | 502 |

| 3750 | 4922 | 1304.8000 | 2020-01-17 10:21:30 | 5164 | 4922 |

| 3750 | 5164 | 20.9450 | 2020-01-17 10:21:36 | 6282 | 5164 |

| 3928 | 6282 | 2514.7000 | 2020-01-17 10:21:40 | 6434 | 6282 |

| 3928 | 6434 | 70.0000 | 2020-01-17 10:21:42 | 6284 | 6434 |

| 3930 | 6284 | 2087.7300 | 2020-01-17 10:41:08 | 6284 | 6284 |

| 3930 | 6284 | 2087.8300 | 2020-01-17 10:42:11 | 6436 | 6284 |

| 3930 | 6436 | 18.0000 | 2020-01-17 10:41:10 | 6436 | 6436 |

| 3930 | 6436 | 18.5000 | 2020-01-17 10:45:11 | 7260 | 6436 |

| 3981 | 7260 | 5.6000 | 2020-01-17 10:21:38 | 7364 | 7260 |

| 3981 | 7364 | 838.7000 | 2020-01-17 10:21:33 | 7468 | 7364 |

| 3981 | 7468 | 12.0000 | 2020-01-17 10:21:29 | 7314 | 7468 |

| 4038 | 7314 | 5.8000 | 2020-01-17 10:19:30 | 7314 | 7314 |

| 4038 | 7314 | 6.6000 | 2020-01-17 10:25:31 | 7418 | 7314 |

| 4038 | 7418 | 252.7000 | 2020-01-17 10:19:29 | 7418 | 7418 |

| 4038 | 7418 | 253.5000 | 2020-01-17 10:30:31 | 7522 | 7418 |

| 4038 | 7522 | 12.0000 | 2020-01-17 10:19:30 | 7522 | 7522 |

| 4038 | 7522 | 12.8000 | 2020-01-17 10:29:31 | | 7522 |

+--------+----------+-----------+---------------------+------------+-----------------+

######### MySQL8.0

mysql> SELECT

a.*,

lead(deviceid) over w as lead_field

FROM

devicecounter a

WINDOW w AS (ORDER BY roomid,deviceid,counter);

#或者下面写法:

mysql> SELECT

a.*,

lead(deviceid) over( ORDER BY roomid,deviceid,counter) as lead_field

FROM

devicecounter a ;

例2:先按roomid分组,再按deviceid,counter排序,类Oracle 的lead() OVER(PARTITION BY ORDER BY)

######### MySQL5.7

mysql> select * from ( SELECT

a.*,

if(@room_id=roomid,@lag,'') as lead_field,

@lead:=deviceid,

@room_id:=roomid

FROM

devicecounter a,(SELECT @lead := '',@room_id:=-1) AS t

ORDER BY roomid desc ,deviceid desc,counter desc )tt

ORDER BY roomid ,deviceid,counter;

+--------+----------+-----------+---------------------+------------+----------------+------------------+

| roomid | deviceid | counter | readtime | lead_field | @lag:=deviceid | @room_id:=roomid |

+--------+----------+-----------+---------------------+------------+----------------+------------------+

| 536 | 147 | 26.0000 | 2020-01-17 10:21:16 | 502 | 147 | 536 |

| 536 | 502 | 872.2700 | 2020-01-17 10:21:19 | | 502 | 536 |

| 3750 | 4922 | 1304.8000 | 2020-01-17 10:21:30 | 5164 | 4922 | 3750 |

| 3750 | 5164 | 20.9450 | 2020-01-17 10:21:36 | | 5164 | 3750 |

| 3928 | 6282 | 2514.7000 | 2020-01-17 10:21:40 | 6434 | 6282 | 3928 |

| 3928 | 6434 | 70.0000 | 2020-01-17 10:21:42 | | 6434 | 3928 |

| 3930 | 6284 | 2087.7300 | 2020-01-17 10:41:08 | 6284 | 6284 | 3930 |

| 3930 | 6284 | 2087.8300 | 2020-01-17 10:42:11 | 6436 | 6284 | 3930 |

| 3930 | 6436 | 18.0000 | 2020-01-17 10:41:10 | 6436 | 6436 | 3930 |

| 3930 | 6436 | 18.5000 | 2020-01-17 10:45:11 | | 6436 | 3930 |

| 3981 | 7260 | 5.6000 | 2020-01-17 10:21:38 | 7364 | 7260 | 3981 |

| 3981 | 7364 | 838.7000 | 2020-01-17 10:21:33 | 7468 | 7364 | 3981 |

| 3981 | 7468 | 12.0000 | 2020-01-17 10:21:29 | | 7468 | 3981 |

| 4038 | 7314 | 5.8000 | 2020-01-17 10:19:30 | 7314 | 7314 | 4038 |

| 4038 | 7314 | 6.6000 | 2020-01-17 10:25:31 | 7418 | 7314 | 4038 |

| 4038 | 7418 | 252.7000 | 2020-01-17 10:19:29 | 7418 | 7418 | 4038 |

| 4038 | 7418 | 253.5000 | 2020-01-17 10:30:31 | 7522 | 7418 | 4038 |

| 4038 | 7522 | 12.0000 | 2020-01-17 10:19:30 | 7522 | 7522 | 4038 |

| 4038 | 7522 | 12.8000 | 2020-01-17 10:29:31 | | 7522 | 4038 |

+--------+----------+-----------+---------------------+------------+----------------+------------------+

######### MySQL8.0

mysql> SELECT

a.*,

lead(deviceid) over w as lead_field

FROM

devicecounter a

WINDOW w AS (partition by roomid ORDER BY deviceid,counter);

#或者下面写法:

mysql>SELECT

a.*,

lead(deviceid) over(partition by roomid ORDER BY deviceid,counter) as lead_field

FROM

devicecounter a ;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值