1. 程式人生 > >慎用mysql的批量更新的方法(語句)

慎用mysql的批量更新的方法(語句)

慎用mysql的批量更新語句

經常使用的是Mysql的單條更新id=id,或者id in(1,2, 3),使用mysql的連表更新使用的比較少。然而使用一次,掉一次坑,也不長記性。在此記錄一下,也是自己的第一條技術文章。

背景

同一張關聯表中記錄的資料重複了,需要刪除(軟刪除)掉一下重複資料,只剩下一條:

// sql code
UPDATE mark_info,
  (SELECT relation_id, mark_info.id
    from mark_info
    WHERE mark_info.relation_type=9
     AND mark_info.
info_key='marked_order' AND info_val='10' AND is_delete=FALSE ) temp_mid SET mark_info.is_delete=True WHERE mark_info.relation_id=temp_mid.relation_id;

這裡可以實現批量聯表更新,但是會遇到幾個問題,需要注意:

  1. 條件指定不全 ,由於是更新部分重複資料,但是where條件並沒有指定出來,所以直接執行會全部更新,然後後悔莫及
  2. 所以需要指定清楚條件temp_mid中使用group分組,然後使用having語句找出指定的資料,才可以;
  3. 為了讓自己有後悔藥吃,在更新的語句set中應該加入指定的更新時間,然後使操作的資料有跡可循

Mysql批量聯表更新的兩種寫法

// 第一種如上  update中指定兩張(**多張**未使用)表,然後通過where條件指定關係  語法中有convert方法,是資料型別的原因
UPDATE user,
  (SELECT
    remark.relation_id as user_id,
    max(remark.id) as max_remark_id
  FROM remark
  where length(remark.relation_id)<=12 and
convert(remark.relation_id, SIGNED) in (SELECT id from user) AND remark.relation_type=6 AND remark.remark_type in (1, 2) GROUP BY remark.relation_id) mid_table set user.last_remark_id=convert(mid_table.max_remark_id, SIGNED) WHERE user.id=convert(mid_table.user_id, SIGNED);

這種方法我感覺更容易理解一點兒,使用時要慎重,如上

// 第二種
UPDATE
  user
set user.last_remark_id=
  (SELECT max_remark_id
   from (
      SELECT
        remark.relation_id as user_id,
        max(remark.id) as max_remark_id
      FROM remark
      where remark.relation_id in (SELECT id from user) AND remark.relation_type=6 AND remark.remark_type in (1, 2)
      GROUP BY remark.relation_id) mid_table
      WHERE mid_table.user_id=user.id
  );

這種方法有點不好理解,多看幾遍,也能接受。

在這裡記錄一下。順便學習著使用markdown語法

2019-01-04 14:46