分别在 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 ;