1. 程式人生 > >mysql insert into ... select from on duplicate update

mysql insert into ... select from on duplicate update

mysql提供了這樣的語法,即當我們往表裡插資料裡,如果資料已經存在(通過主鍵或唯一索引確定),我們可以對已存在的記錄做更新操作。如:

INSERT USER(id,username) VALUES(1,'張三丰') ON DUPLICATE KEY UPDATE username='王老五'

上面的sql意思是,如果id為1的記錄不存在,則insert一條id=1、username=張三丰的記錄;否,將id為1記錄的username改為王老五。這只是插入單行資料,mysql甚至支援批量操作,如:

INSERT INTO table (id,a,b,c) select (id,a,b,c) from xxx
ON DUPLICATE KEY UPDATE a=VALUES(a),b=VALUES(b),c=VALUES(c)

即通過insert into ...from 來批量插入,然後通過values(xxx)來取得結果集中對應的欄位值。

mysql這一強大的功能,讓我們能夠在一條sql裡處理以前必須在儲存過程裡完成的操作。我們專案有個需求,定時統計文章的閱讀數、收藏數、評論數,用一張表來儲存統計數,我的sql如下:

INSERT INTO `composition_article_statistics` (
  `article_id`,
  `read_count`,
  `concern_count`,
  `paragraph_count`,
  `discuss_count`
)
SELECT
  id,
  (SELECT
    COUNT(1)
  FROM
    composition_user_read_log
  WHERE ARTICLE_ID = ca.`id`) read_count,
  (SELECT
    COUNT(1)
  FROM
    composition_concren
  WHERE `STATUS` = 1
    AND ARTICLE_ID = ca.`id`) concern_count,
  (SELECT
    COUNT(1)
  FROM
    composition_article_paragraph
  WHERE `status` = 1
    AND article_id = ca.id) paragraph_count,
  (SELECT
    COUNT(1)
  FROM
    composition_common_discuss
  WHERE TYPE = 2
    AND STATUS = 1
    AND target_id = ca.id) discuss_count
FROM
  composition_article ca
  ON DUPLICATE KEY
  UPDATE
    `read_count` =
    VALUES
      (read_count),
      `concern_count` =
      VALUES
        (concern_count),
        `paragraph_count` =
        VALUES
          (paragraph_count),
          `discuss_count` =
          VALUES
            (`discuss_count`)

不管是舊文章還是新文章都能統計到,完美解決了我的問題。