国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

MySQL 【去重留一】一條sql語句完成 思路總結

wua_wua2012 / 660人閱讀

摘要:查了資料,請教了大佬之后得出了一個很便利的語句,這里分享下這段語句和思路。需求分析數據庫中存在重復記錄,刪除保留其中一條是否重復判斷基準為多個字段解決方案碰到這個需求的時候,心里大概是有思路的。

原文是在我自己博客中,小伙伴也可以點閱讀原文進行跳轉查看,還有好聽的背景音樂噢~

????前幾天在做一個需求的時候,需要清理mysql中重復的記錄,當時的想法是通過代碼遍歷寫出來,然后覺得太復雜,心里想著應該可以通過一個sql語句來解決問題的。查了資料,請教了大佬之后得出了一個很便利的sql語句,這里分享下這段sql語句和思路。

需求分析

數據庫中存在重復記錄,刪除保留其中一條(是否重復判斷基準為多個字段)

解決方案

碰到這個需求的時候,心里大概是有思路的。最快想到的是可以通過一條sql語句來解決,無奈自己對于復雜sql語句的道行太淺,所以想找大佬幫忙。

找人幫忙

因為這個需求有點著急,所以最開始想到的是,可以找這方面的同行來解決,然后分享這個問題給@趙七七同學,結果這貨隨便百度了一下,就甩給我一個從未用過的sql語句,讓我自己嘗試,心里萬匹那啥啥啥奔騰而過...

自己百度

找到了一條sql語句:

DELETE
FROM
    vitae a
WHERE
    (a.peopleId, a.seq) IN (
        SELECT
            peopleId,
            seq
        FROM
            vitae
        GROUP BY
            peopleId,
            seq
        HAVING
            count(*) > 1
    )
AND rowid NOT IN (
    SELECT
        min(rowid)
    FROM
        vitae
    GROUP BY
        peopleId,
        seq
    HAVING
        count(*) > 1
)

這條語句是在【MySQL中刪除重復數據只保留一條】這篇文章里找到的。這條sql思路很明顯,有以下3步:

SELECT peopleId, seq FROM vitae GROUP BY peopleId, seq HAVING count(*) > 1查詢出表中重復記錄作為條件

SELECT min(rowid) FROM vitae GROUP BY peopleId, seq HAVING count(*) > 1查詢出表中重復記錄中ID最小的值為第二個條件

最后根據以上兩個條件,刪除重復記錄中最小ID的其余重復記錄

但是很無奈的是,運行這條語句出現了錯誤,大致報錯意思是,不能在查詢的時候同時更新這個表。

代碼解決

根據上面這個sql語句想到或許可以通過代碼的方式,兩步來達到同樣的目的:

先取出重復的數據集

根據查詢到的數據集,循環刪除其余的重復數據

想法是有了,寫出來也很快,但是一運行嚇我一跳,竟然需要116s左右,然后自己就想一定要找到可以使用的sql語句,貼一下代碼和運行結果:

完美的【去重留一】SQL

最后在一個技術群里得到了完美的答案,看這條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
    ) t2
WHERE
    consum_record.user_id = t2.user_id 
    and consum_record.monetary = t2.monetary
    and consum_record.consume_time  = t2.consume_time
AND consum_record.id > t2.id;

上面這條sql語句,仔細看一下,揣摩出思路也不難,大概也分為3步來理解:

(SELECT min(id) id, user_id, monetary, consume_time FROM consum_record GROUP BY user_id, monetary, consume_time HAVING count(*) > 1 ) t2 查詢出重復記錄形成一個集合(臨時表t2),集合里是每種重復記錄的最小ID

consum_record.user_id = t2.user_id and consum_record.monetary = t2.monetary and consum_record.consume_time = t2.consume_time 關聯判斷重復基準的字段

根據條件,刪除原表中id大于t2中id的記錄

看到這個語句的時候,心里想這也太厲害了。這么一個簡單的sql語句,竟然可以解決這么復雜的問題,漲姿勢了~
運行起來也超級快,原先的代碼循環執行,需要116s左右,而這里0.3s就可以了,厲害了~

總結

作為一個php程序猿,按理來說sql這里是不能拖后腿的,無奈實際中,需要忙碌的事情太多,現在的sql水平也只是處于在一個普通的層次中,以后找機會一定要補一下這方面的知識。

資源

為了方便小伙伴測試,已經把這個數據表傳上來了,有mysql工具的話,導入即可。consume_record.sql
今天就分享到這里啦。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/26162.html

相關文章

  • SegmentFault 技術周刊 Vol.42 - MySQL:從刪庫到跑路

    摘要:肖鵬微博數據庫那些事兒肖鵬,微博研發中心技術經理,主要負責微博數據庫相關的業務保障性能優化架構設計,以及周邊的自動化系統建設。經歷了微博數據庫各個階段的架構改造,包括服務保障及體系建設微博多機房部署微博平臺化改造等項目。 showImg(https://segmentfault.com/img/bV24Gs?w=900&h=385); 對于手握數據庫的開發人員來說,沒有誤刪過庫的人生是...

    aboutU 評論0 收藏0
  • MySQL必知必會:組合查詢(Union)

    摘要:本文參考必知必會工作實踐融合組合查詢定義在大多數開發中,使用一條查詢就會返回一個結果集。在查詢結果集中幫我們自動去除了重復的行重復的行是李四,把兩條李四合并了。注意由于在多表組合查詢時候,可能表字段并不相同。 本篇文章主要介紹使用Union操作符將多個SELECT查詢組合成一個結果集。本文參考《Mysql必知必會》+工作實踐融合 組合查詢 定義 在大多數開發中,使用一條SELECT查詢...

    用戶83 評論0 收藏0

發表評論

0條評論

wua_wua2012

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<