2017-06-29 48 views
1

這是我在MySQL現有表
如何遍歷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 

我想更新表,並插入一個獨特的UUID,而不是基於零的名稱是否相同,時間戳爲1分鐘,每次其他與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 

請讓我知道我怎麼寫SQL腳本來做到這一點使用MySQL的工作臺..

+0

貴表包含一個唯一的ID列標識行? – Barmar

+0

UUID從哪裏來? – Barmar

+0

是的..我有一個自動增量ID列 – Sharvil

回答

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 

如果要更新,做一個,和更新加入您的原始表。


這由幾個步驟進行。首先,你需要訂購你的數據,並確定此時你需要「改變組」(我把那個叫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 

現在,您可以通過連接到的表改變group_number到UUID (1,UID1),(2,UID2)等的元組:

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 

通過用最後一個SQL的定義代替ttt2ttt,你可以在一個查詢中得到你想要的東西......雖然是「怪物一個」。

注意:這個查詢可能會非常低效;而且,如果您正在進行編程,您可能只需循環訪問已排序的數據並確定何時需要生成新的UUID。

您可以檢查一切dbfiddle here

+0

謝謝..幫了很多.. – Sharvil

+0

不客氣Sharvil。如果你認爲這個問題已經被回答了,那麼把它標記爲*接受的*或多或少是習慣的,這樣人們就可以專注於已經沒有回答的*的廣泛列表。 – joanolo

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"); 
相關問題