如何更新 number
列,使其计数为 1,2,3,4,... 然后当另一列 booking_id
更改时再次从 1 重新开始?
这是我到目前为止所得到的:
SET @pos := 0;
SET @last := 0;
UPDATE booking_segments
SET number = (SELECT @pos := if(booking_id = @last, @pos + 1, 1)), @last := booking_id
where 1
ORDER BY booking_id, pickup_time_utc;
我认为这样的事情应该可行,但我不知道如何在不产生语法错误的情况下消除其中的 @last := booking_id
位。如果 MySQL 和像 JS 这样的逗号运算符,我可以做到,但我不确定 SET
block 中还有什么可能有效。
我想通了,但是有没有更简单的方法来做到这一点?
SET @pos := 0;
SET @last := 0;
UPDATE booking_segments
SET number = @tmp := (SELECT @pos := if(booking_id = @last, @pos + 1, 1)),
number = @last := booking_id,
number = @tmp
where 1
ORDER BY booking_id,pickup_time_utc ;
Here's the result如果您无法想象这一点。
+----+------------+--------+---------------------+
| id | booking_id | number | pickup_time_utc |
+----+------------+--------+---------------------+
| 3 | 2 | 1 | 2015-02-22 18:00:00 |
+----+------------+--------+---------------------+
| 7 | 2 | 2 | 2015-02-23 04:00:00 |
+----+------------+--------+---------------------+
| 8 | 5 | 1 | 2015-06-06 21:00:00 |
+----+------------+--------+---------------------+
| 9 | 5 | 2 | 2015-06-07 08:15:00 |
+----+------------+--------+---------------------+
| 10 | 6 | 1 | 2015-04-11 15:00:00 |
+----+------------+--------+---------------------+
| 11 | 6 | 2 | 2015-04-12 05:30:00 |
+----+------------+--------+---------------------+
| 16 | 8 | 1 | 2015-07-28 08:20:00 |
+----+------------+--------+---------------------+
| 17 | 8 | 2 | 2015-07-28 10:00:00 |
+----+------------+--------+---------------------+
| 18 | 9 | 1 | 2015-07-01 15:50:00 |
+----+------------+--------+---------------------+
| 19 | 10 | 1 | 2015-09-13 06:00:00 |
+----+------------+--------+---------------------+
| 20 | 11 | 1 | 2015-08-01 23:30:00 |
+----+------------+--------+---------------------+
| 21 | 11 | 2 | 2015-08-02 07:00:00 |
+----+------------+--------+---------------------+
| 22 | 12 | 1 | 2015-08-08 20:00:00 |
+----+------------+--------+---------------------+
| 23 | 13 | 1 | 2015-09-05 21:00:00 |
+----+------------+--------+---------------------+
| 24 | 14 | 1 | 2015-09-19 20:30:00 |
+----+------------+--------+---------------------+
| 25 | 15 | 1 | 2015-08-29 21:15:00 |
+----+------------+--------+---------------------+
| 26 | 16 | 1 | 2015-09-10 03:15:00 |
+----+------------+--------+---------------------+
| 37 | 16 | 2 | 2015-09-10 08:00:00 |
+----+------------+--------+---------------------+
| 28 | 17 | 1 | 2015-08-12 22:00:00 |
+----+------------+--------+---------------------+
| 29 | 18 | 1 | 2015-08-11 08:00:00 |
+----+------------+--------+---------------------+
| 30 | 19 | 1 | 2015-08-15 21:00:00 |
+----+------------+--------+---------------------+
| 32 | 20 | 1 | 2016-06-09 09:05:00 |
+----+------------+--------+---------------------+
| 31 | 20 | 2 | 2016-06-10 12:00:00 |
+----+------------+--------+---------------------+
| 33 | 21 | 1 | 2015-09-10 05:00:00 |
+----+------------+--------+---------------------+
| 34 | 22 | 1 | 2015-09-10 02:00:00 |
+----+------------+--------+---------------------+
| 35 | 22 | 2 | 2015-09-10 04:00:00 |
+----+------------+--------+---------------------+
| 36 | 22 | 3 | 2015-09-10 06:45:00 |
+----+------------+--------+---------------------+
| 38 | 23 | 1 | 2015-09-10 04:00:00 |
+----+------------+--------+---------------------+
| 39 | 23 | 2 | 2015-09-10 09:45:00 |
+----+------------+--------+---------------------+
| 40 | 24 | 1 | 2015-09-10 04:30:00 |
+----+------------+--------+---------------------+
| 41 | 24 | 2 | 2015-09-10 06:45:00 |
+----+------------+--------+---------------------+
| 67 | 38 | 1 | 2016-01-02 16:20:00 |
+----+------------+--------+---------------------+
| 68 | 38 | 2 | 2016-01-03 07:00:00 |
+----+------------+--------+---------------------+
| 69 | 38 | 3 | 2016-01-03 10:00:00 |
+----+------------+--------+---------------------+
我目前使用的版本是 10.1.14-MariaDB。
最佳答案
MariaDB started supporting Window/Analytic functions since version 10.2 ;所以如果你可以升级,你可以利用 Row_Number()
功能。
在派生表中,我们可以首先获取每一行的“行号”,在 booking_id
的分区上按 pickup_time_utc
升序排列。然后我们可以连接回主表,以更新 number
列。查询将简单如下:
UPDATE booking_segments AS bs
JOIN (SELECT id,
Row_number()
OVER (
partition BY booking_id
ORDER BY pickup_time_utc ASC) AS rn
FROM booking_segments) AS dt
ON dt.id = bs.id
SET bs.number = dt.rn
关于MySQL/MariaDB 更新计数器分组依据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57602647/