MySQL一條語句去重留一

一條語句刪除數據庫中的重複記錄(數據量較大,百萬級數據,注意性能問題)

此類問題比較常見,在平常的開發當中,如何使用一條語句就能夠做到呢? 並且效率還要很快,下邊給出一種刪除重複數據保留一條的方案. 希望大家有好的思路可以評論分享.這邊爲了方便理解,給出我本地使用的sql案例,方便大家測試和修改

首先說下思路:

  1. 把重複數據查出來作爲一個臨時表temp
  2. 保留一組重複數據中主鍵id最小的記錄(刪除的時候要用)
  3. 兩個表連接進行刪除操作,刪除Where條件:重複條件相同,並且id>min(id)

數據表字段及說明

consum_record表數據及結構下載
表結構如下:

id主鍵,注意重複的列爲user_id(用戶id),monetary(消費金額),consume_time(消費時間),也就是說,同一個顧客同一個時間消費金額數是不可能存在多條數據的, 我們要對數據庫中記錄坐下排重

其中摘錄出來幾條重複數據供大家理解題設

id user_id monetary consume_time consume_type
2552 321 4 1495075537 1
2553 321 4 1495075537 1
2554 321 4 1495079932 1
2555 111 6 1495079932 1
2556 111 6 1495079932 1
2557 156 12 1495079939 1
2558 156 12 1495079939 1
2559 156 12 1495079939 1

SQL展示

DELETE consum_record
FROM
    consum_record, 
    (
        SELECT
            min(id) id,
            user_id,
            monetary,
            consume_time
        FROM
            consum_record
        GROUP BY
            user_id,
            monetary,
            consume_time
        HAVING
            count(*) > 1
    ) temp
WHERE
    consum_record.user_id = temp.user_id 
    and consum_record.monetary = temp.monetary
    and consum_record.consume_time  = temp.consume_time
AND consum_record.id > temp.id;

思路:

  • 首先就是將user_id,monetary,consume_time這三個字段進行group by,將count(*)>1篩選出來

min(id) id 每個重複組當中的最小id很關鍵,刪除數據的時候做篩選使用 也可以使用max(id)

        SELECT
            min(id) id,#每個重複組當中的最小id很關鍵,刪除數據的時候做篩選使用 也可以使用max(id)
            user_id,
            monetary,
            consume_time
        FROM
            consum_record
        GROUP BY
            user_id,
            monetary,
            consume_time
        HAVING
            count(*) > 1
  • 接下來使用基礎表,和查出來的重複數據做關聯(根據三個重複字段做關聯), 然後根據每組重複數據consumer_record.id> temp.id 刪除相應數據

總結:

要深刻理解group by的原理, 根據相應的條件分組

刪除的時候temp表其實就是作爲一個篩選條件而存在的表,這時候可以兩個表做關聯篩選出需要的行

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章