【问题标题】:MySQL/MariaDB update counter group byMySQL/MariaDB 更新计数器组按
【发布时间】:2019-08-22 05:38:21
【问题描述】:

如何更新 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 块内还有什么有效的。


我想出了一些办法,但有没有一种不那么贫民窟的方式来做到这一点?

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。

【问题讨论】:

标签: mysql mariadb


【解决方案1】:

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  

【讨论】:

    猜你喜欢
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 2015-05-04
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    • 2022-01-06
    相关资源
    最近更新 更多