这是我在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分钟之内插入一个唯一的UUID而不是null,并且org_id在SQL中是相同的。
期望的输出:
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脚本来实现此目的..
答案 0 :(得分:1)
你可以用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 ;
你会得到:
name | date_time | org_id | uuid :--- | :------------------ | -----: | :----------------------------------- KK | 2017-01-01 11:37:33 | 1 | 636c0fcf-5d3f-11e7-8f8c-00163ebcde7e SK | 2017-04-19 01:36:34 | 2 | 636c107a-5d3f-11e7-8f8c-00163ebcde7e SK | 2017-04-19 01:36:53 | 2 | 636c107a-5d3f-11e7-8f8c-00163ebcde7e SK | 2017-04-19 01:37:23 | 2 | 636c107a-5d3f-11e7-8f8c-00163ebcde7e TK | 2017-02-11 01:37:20 | 5 | 636c108d-5d3f-11e7-8f8c-00163ebcde7e TK | 2017-02-11 01:37:31 | 5 | 636c108d-5d3f-11e7-8f8c-00163ebcde7e
如果您想要更新,请使用该表格加入原始表格,然后更新。
这可以通过几个步骤完成......首先,您需要订购数据,并确定您需要在哪个时间点更改组&#34; (我称之为step
)。这将为您提供一个中间表(ttt):
CREATE TABLE ttt AS
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
ORDER BY
`name`, `date_time`, `org_id` ;
表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
从该表中,对于每一行,计算SUM(all preceding steps)
。这是由以下人员完成的:
CREATE TABLE ttt2 AS
SELECT
`name`, `date_time`, `org_id`,
(SELECT
sum(step)
FROM
ttt
WHERE
ttt.name <= t.name AND ttt.date_time <= ttt.date_time
) AS group_number
FROM
t
ORDER BY
`name`, `date_time`, `org_id` ;
然后你会得到第二个中间表,我称之为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
现在,您通过加入(1,UID1),(2,UID2)等表来将group_number
更改为UUID。元组:
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
通过将ttt2
和ttt
替换为最后一个SQL上的定义,您可以在一个查询中得到您想要的内容...尽管一个&#34;怪物一个&#34;。
注意:此查询可能非常低效;并且,如果您正在编程,您可能只需循环查看已排序的数据并决定何时需要生成新的UUID,就可能更好。
您可以查看 dbfiddle here
上的所有内容答案 1 :(得分:0)
感谢您的帮助..
我也想出了这个问题的一个大致解决方案:
这是我的疑问:
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");