我操作MySQL的驚險一幕( 二 )


我:如何解決的?
組長:將這個事務回滾解決的,你更新的 SQL 怎么寫的?(努力回想)
于是寫出了上面寫的 SQL:
UPDATE b AS tb, (SELECT create_time FROM a) AS ta SET tb.create_time = ta.create_time;組長:你為什么這樣寫?不應該把子查詢寫在 SET tb.create_time 后面嗎?
我:對啊,我一開始就是把這個子查詢寫在它后面的,但是提示我語法錯誤,我就換了一種寫法 。
組長:那你寫寫你說提示錯誤的 SQL 。
于是我又丟出來一個 SQL:
UPDATE b SET create_time = (SELECT create_time FROM a);實際上,這條 SQL 也是不行的 , 子查詢返回的結果不止一行,而當前 SET 是更新某一行的 。
正確的寫法是:
UPDATE b AS tbSET create_time = (SELECT create_time FROM a AS ta WHERE tb.id = ta.id AND tb.name = ta.name)WHERE tb.id = (SELECT tb.id FROM a AS ta WHERE tb.id = ta.id AND tb.name = ta.name)

我操作MySQL的驚險一幕

文章插圖
博客園-SQL把一個表中數據更新到另一個表的多種方法
最后組長深思 , 你 B 表已經有 2 萬多條記錄了,A 表也有 2 萬多條記錄 , 你這樣更新,每一次都需要子查詢查出 A 表的 2 萬多條記錄,B 也有 2 萬多條記錄 , 這樣成笛卡爾積了,你知道什么是笛卡爾積吧?2 萬 × 2 萬 = 4 億的記錄行了,難怪這么久 。
總結情況:漏了某一個字段 X,需要將 A 表的這個字段列值更新到 B 表
條件:A 中的 id 字段的值等于 B表中的 id 字段的值 且 A 中的 name 字段的值等于 B 中 name 字段的值(條件為什么這樣寫?) 。
條件這樣寫主要是因為 表和表之間的關聯關系 可能有多個字段,此處只選二個字段,多個依此類推 。
操作:
  • 一張表的數據插入到另一張表,可以這樣寫:
INSERT INTO 目標表(字段1, 字段2, ...) SELECT 字段1, 字段2, ... FROM 來源表 WHERE 條件;
  • 批量更新一張表的某個字段到另一張表,那么 SQL 可以類似這樣寫:
UPDATE b AS tbSET create_time = (SELECT create_time FROM a AS ta WHERE tb.id = ta.id AND tb.name = ta.name)WHERE tb.id = (SELECT tb.id FROM a AS ta WHERE tb.id = ta.id AND tb.name = ta.name)所謂洗數據:在我的理解中,就是把舊數據 , 按照新數據的規則把舊數據不正確的值修改正確,同時把這些舊數據插入到新數據中,成為新數據 。舉個例子 , A 表中的 province_id,值為 10 代表 廣東,而 B 表中的 province_id  , 值為 19 代表 廣東,把 A 表中的數據插入到 B 表的過程中,把值為 10 修改為 19 , 這樣插入的數據才能在 B 表中正確表示 廣東,這個過程就是「洗數據」,當然 , 也可以在插入后再修改,不管過程是怎樣,最終能把數據的值修改正確 , 就是洗數據!
教訓:
  1. 數據量大的表,少在測試環境操作,要操作盡量保證寫的 SQL 是正確的,能在本地環境操作就現在本地環境操作!
  2. 能用 Java 代碼進行操作,優先寫 Java 代碼操作!
最后的最后由本人水平所限,難免有錯誤以及不足之處,屏幕前的靚仔靚女們 如有發現,懇請指出!
最后 , 謝謝你看到這里,謝謝你認真對待我的努力,希望這篇博客對你有所幫助!
你輕輕地點了個贊,那將在我的心里世界增添一顆明亮而耀眼的星!

推薦閱讀