最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一條sql語句完成MySQL去重留一

 更新時間:2017年12月04日 08:49:23   作者:命中水  
在使用mysql時,有時需要查詢出某個字段不重復的記錄,雖然mysql提供 有distinct這個關鍵字來過濾掉多余的重復記錄只保留一條,但往往只用它來返回不重復記錄的條數,而不是用它來返回不重記錄的所有值。

前幾天在做一個需求的時候,需要清理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語句想到或許可以通過代碼的方式,兩步來達到同樣的目的:

先取出重復的數據集

根據查詢到的數據集,循環(huán)刪除其余的重復數據

想法是有了,寫出來也很快,但是一運行嚇我一跳,竟然需要 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 關聯(lián) 判斷重復基準的字段

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

看到這個語句的時候,心里想這也太厲害了。這么一個簡單的sql語句,竟然可以解決這么復雜的問題,漲姿勢了~

運行起來也超級快,原先的代碼循環(huán)執(zhí)行,需要 116s 左右,而這里 0.3s 就可以了,厲害了~

總結

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

今天就分享到這里啦。

相關文章

  • 詳解MySQL高可用MMM搭建方案及架構原理

    詳解MySQL高可用MMM搭建方案及架構原理

    本篇文章主要介紹搭建MMM方案以及MMM架構的原理。這里不介紹主從、主主的搭建方法,MMM方案不適用對數據一致性要求很高的業(yè)務。下面一起來學習學習。
    2016-08-08
  • mysql父子集查詢(根據父級查詢所有子集)

    mysql父子集查詢(根據父級查詢所有子集)

    某些場景可能需要維護一些有父子關系的數據,本文主要介紹了mysql父子集查詢(根據父級查詢所有子集),具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • mysql中json類型字段的基本用法實例

    mysql中json類型字段的基本用法實例

    大家應該都知道m(xù)ysql中的字段可以使用json的格式來進行存儲,下面這篇文章主要給大家介紹了關于mysql中json類型字段的基本用法,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • MySQL回滾日志(undo?log)的作用和使用詳解

    MySQL回滾日志(undo?log)的作用和使用詳解

    undo?log是innodb引擎的一種日志,在事務的修改記錄之前,會把該記錄的原值先保存起來再做修改,以便修改過程中出錯能夠恢復原值或者其他的事務讀取,這篇文章主要給大家介紹了關于MySQL回滾日志(undo?log)的作用和使用的相關資料,需要的朋友可以參考下
    2022-04-04
  • MySQL8.0就地升級到MySQL8.4.0的方法

    MySQL8.0就地升級到MySQL8.4.0的方法

    本文主要介紹了MySQL8.0就地升級到MySQL8.4.0的方法,文中通過代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-06-06
  • redhat7.1 安裝mysql 5.7.10步驟詳解(圖文詳解)

    redhat7.1 安裝mysql 5.7.10步驟詳解(圖文詳解)

    這篇文章主要介紹了redhat7.1 安裝mysql 5.7.10的步驟詳細介紹本文圖文并茂給大家介紹的非常詳細,需要的朋友可以參考下
    2016-11-11
  • mysql啟動提示mysql.host 不存在,啟動失敗的解決方法

    mysql啟動提示mysql.host 不存在,啟動失敗的解決方法

    我將s9當眾原來的mysql4.0刪除后,重新裝了個mysql5.0,啟動過程中報一下錯誤,啟動失敗,查了一下群里面的老帖子也沒有個具體的明確說明
    2011-10-10
  • MySQL如何創(chuàng)建視圖

    MySQL如何創(chuàng)建視圖

    這篇文章主要介紹了MySQL如何創(chuàng)建視圖,幫助大家更好的理解和學習MySQL,感興趣的朋友可以了解下
    2020-08-08
  • MySql索引的作用以及對索引的理解

    MySql索引的作用以及對索引的理解

    這篇文章主要給大家介紹了關于MySql索引的作用以及對索引的理解,MySQL索引的建立對于MySQL的高效運行是很重要的,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-06-06
  • 查詢MySQL中的樹型表兩種方法

    查詢MySQL中的樹型表兩種方法

    在 MySQL中查詢樹型表(即具有層級結構的表)可以使用遞歸查詢或者使用嵌套集模型,下面介紹兩種方法查詢MySQL中的樹型表,感興趣的朋友一起看看吧
    2024-01-01

最新評論

灌云县| 永德县| 广水市| 那曲县| 五华县| 蚌埠市| 瑞安市| 常熟市| 大名县| 酉阳| 积石山| 垣曲县| 长子县| 吐鲁番市| 弋阳县| 金门县| 景泰县| 平顺县| 新宁县| 孙吴县| 萝北县| 永平县| 抚顺市| 大邑县| 藁城市| 广宁县| 东台市| 新泰市| 上高县| 白河县| 新绛县| 太湖县| 化州市| 康马县| 吴桥县| 长兴县| 扶沟县| 察雅县| 山丹县| 琼结县| 大理市|