如何循环MySQL中的行并根据下一行的值插入数据?

如何循环MySQL中的行并根据下一行的值插入数据?,mysql,sql,mysql-workbench,Mysql,Sql,Mysql Workbench,这是我在MySQL中的现有表 name UUID date_time org_id SK null 2017-04-19 01:36:34 2 SK null 2017-04-19 01:36:53 2 SK null 2017-04-19 01:37:23 2 TK null 2017-02-11 01:37:20 5 TK null 2017-02-11 01:37:31 5 KK nul

这是我在MySQL中的现有表

name  UUID  date_time             org_id
SK    null  2017-04-19 01:36:34    2
SK    null  2017-04-19 01:36:53    2
SK    null  2017-04-19 01:37:23    2
TK    null  2017-02-11 01:37:20    5
TK    null  2017-02-11 01:37:31    5
KK    null  2017-01-01 11:37:33    1
我想更新这个表,并根据名称是否相同、时间戳是否在彼此之间的1分钟内以及SQL中的组织id是否相同,插入一个唯一的UUID而不是null

期望输出:

name  UUID  date_time             org_id
SK    we23  2017-04-19 01:36:34    2
SK    we23  2017-04-19 01:36:53    2
SK    we23  2017-04-19 01:37:23    2
TK    rt56  2017-02-11 01:37:20    5
TK    rt56  2017-02-11 01:37:31    5
KK    yu77  2017-01-01 11:37:33    1

请让我知道如何使用MySQL workbench编写SQL脚本来完成此操作。

您可以使用MySQL来完成此操作,但这相当复杂,因为它需要几个子查询

SELECT
    name, date_time, org_id, uuid
FROM
    (
        SELECT
            `name`, `date_time`, `org_id`, 
            (SELECT 
                sum(step) 
             FROM
             (
                  SELECT
                      t1.`name`, t1.`date_time`, t1.`org_id`,
                      case when exists 
                        (SELECT 1
                         FROM t AS t2 
                         WHERE t2.`name` = t1.`name` 
                           AND timestampdiff(second, t1.date_time, t2.date_time) < 60
                           AND t2.date_time > t1.date_time
                           ) 
                      then 0
                      else 1
                      end AS step
                  FROM
                      t AS t1
             ) AS ttt
             WHERE
                ttt.name <= t.name AND ttt.date_time <= ttt.date_time
            ) AS group_number
        FROM
            t
    ) AS ttt2
    JOIN
    (
        SELECT 1 AS group_number, UUID() AS `uuid`
        UNION
        SELECT 2 AS group_number, UUID() AS `uuid`
        UNION
        SELECT 3 AS group_number, UUID() AS `uuid`
        -- and as many as needed
    ) u ON u.group_number = ttt2.group_number
ORDER BY
    name, date_time ;
表ttt为:

name | date_time | org_id | step :--- | :------------------ | -----: | ---: KK | 2017-01-01 11:37:33 | 1 | 1 SK | 2017-04-19 01:36:34 | 2 | 0 SK | 2017-04-19 01:36:53 | 2 | 0 SK | 2017-04-19 01:37:23 | 2 | 1 TK | 2017-02-11 01:37:20 | 5 | 0 TK | 2017-02-11 01:37:31 | 5 | 1 您将得到第二个中间表,我称之为
tt2

name | date_time | org_id | group_number :--- | :------------------ | -----: | -----------: KK | 2017-01-01 11:37:33 | 1 | 1 SK | 2017-04-19 01:36:34 | 2 | 2 SK | 2017-04-19 01:36:53 | 2 | 2 SK | 2017-04-19 01:37:23 | 2 | 2 TK | 2017-02-11 01:37:20 | 5 | 3 TK | 2017-02-11 01:37:31 | 5 | 3 你终于得到了你想要的

name | date_time | org_id | uuid :--- | :------------------ | -----: | :----------------------------------- KK | 2017-01-01 11:37:33 | 1 | 636bd83f-5d3f-11e7-8f8c-00163ebcde7e SK | 2017-04-19 01:36:34 | 2 | 636bd8b9-5d3f-11e7-8f8c-00163ebcde7e SK | 2017-04-19 01:36:53 | 2 | 636bd8b9-5d3f-11e7-8f8c-00163ebcde7e SK | 2017-04-19 01:37:23 | 2 | 636bd8b9-5d3f-11e7-8f8c-00163ebcde7e TK | 2017-02-11 01:37:20 | 5 | 636bd8c8-5d3f-11e7-8f8c-00163ebcde7e TK | 2017-02-11 01:37:31 | 5 | 636bd8c8-5d3f-11e7-8f8c-00163ebcde7e 名称|日期|时间|组织| id | uuid :--- | :------------------ | -----: | :----------------------------------- KK | 2017-01-01 11:37:33 | 1 | 636bd83f-5d3f-11e7-8f8c-00163ebcde7e SK | 2017-04-19 01:36:34 | 2 | 636bd8b9-5d3f-11e7-8f8c-00163ebcde7e SK | 2017-04-19 01:36:53 | 2 | 636bd8b9-5d3f-11e7-8f8c-00163ebcde7e SK | 2017-04-19 01:37:23 | 2 | 636bd8b9-5d3f-11e7-8f8c-00163ebcde7e TK | 2017-02-11 01:37:20 | 5 | 636bd8c8-5d3f-11e7-8f8c-00163ebcde7e TK | 2017-02-11 01:37:31 | 5 | 636bd8c8-5d3f-11e7-8f8c-00163ebcde7e 通过将
ttt2
ttt
替换为上一个SQL上的定义,您可以在一个查询中得到所需的内容。。。虽然是“怪物一号”

注意:此查询可能效率极低;而且,如果您正在编程,您可能会更好地通过循环排序数据并决定何时需要生成新的UUID

您可以在dbfiddle上查看所有内容

谢谢您的帮助。
我还找到了这个问题的近似解决方案:
我的问题是:

update table as u, 
        (SELECT UUID() as UUID, name, org_id,date_time 
        FROM table 
        group by name, org_id, DATE_FORMAT(date_time, "%Y-%m-%e %H-%i")) as b
set u.UUID = b.UUID
where (u.name = b.name OR (u.name is null and u.name is null)) 
    and (u.org_id = b.org_id OR ( u.org_id is null and b.org_id is null)) 
    and DATE_FORMAT(u.date_time, "%Y-%m-%e %H-%i") = DATE_FORMAT(b.date_time, "%Y-%m-%e %H-%i");

您的表是否包含标识行的唯一ID列?UUID来自何处?是。。我有一个自动递增的ID列,UUID将由MySQL的UUID()函数生成。。只是基于上述条件,它在团体中应该是独一无二的。不客气,沙维尔。如果你认为这个问题已经被问过了,那么或多或少习惯性的做法是将其标记为已被接受,这样人们就可以把注意力集中在大量尚未回答的问题上。 name | date_time | org_id | group_number :--- | :------------------ | -----: | -----------: KK | 2017-01-01 11:37:33 | 1 | 1 SK | 2017-04-19 01:36:34 | 2 | 2 SK | 2017-04-19 01:36:53 | 2 | 2 SK | 2017-04-19 01:37:23 | 2 | 2 TK | 2017-02-11 01:37:20 | 5 | 3 TK | 2017-02-11 01:37:31 | 5 | 3
SELECT
    name, date_time, org_id, uuid
FROM
    ttt2 
    JOIN
    (
        SELECT 1 AS group_number, UUID() AS `uuid`
        UNION
        SELECT 2 AS group_number, UUID() AS `uuid`
        UNION
        SELECT 3 AS group_number, UUID() AS `uuid`
        UNION
        SELECT 4 AS group_number, UUID() AS `uuid`
        -- and as many as you might need
    ) u ON u.group_number = ttt2.group_number 
ORDER BY
    name, date_time ;
name | date_time | org_id | uuid :--- | :------------------ | -----: | :----------------------------------- KK | 2017-01-01 11:37:33 | 1 | 636bd83f-5d3f-11e7-8f8c-00163ebcde7e SK | 2017-04-19 01:36:34 | 2 | 636bd8b9-5d3f-11e7-8f8c-00163ebcde7e SK | 2017-04-19 01:36:53 | 2 | 636bd8b9-5d3f-11e7-8f8c-00163ebcde7e SK | 2017-04-19 01:37:23 | 2 | 636bd8b9-5d3f-11e7-8f8c-00163ebcde7e TK | 2017-02-11 01:37:20 | 5 | 636bd8c8-5d3f-11e7-8f8c-00163ebcde7e TK | 2017-02-11 01:37:31 | 5 | 636bd8c8-5d3f-11e7-8f8c-00163ebcde7e
update table as u, 
        (SELECT UUID() as UUID, name, org_id,date_time 
        FROM table 
        group by name, org_id, DATE_FORMAT(date_time, "%Y-%m-%e %H-%i")) as b
set u.UUID = b.UUID
where (u.name = b.name OR (u.name is null and u.name is null)) 
    and (u.org_id = b.org_id OR ( u.org_id is null and b.org_id is null)) 
    and DATE_FORMAT(u.date_time, "%Y-%m-%e %H-%i") = DATE_FORMAT(b.date_time, "%Y-%m-%e %H-%i");