MySQL實現(xiàn)去重的幾種方法小結
前言
在MySQL中,SELECT DISTINCT 和 GROUP BY 可以用來去除重復記錄,二者有相似的功能,但在某些情況下有所不同
1. DISTINCT
SELECT DISTINCT 用于從表中選擇唯一的記錄,去除所有重復的數(shù)據(jù)行
直接作用于結果集,并去除所有指定列上的重復值
SELECT DISTINCT equipment_no FROM equipment_check_order;
在單列去重的場景下,效率較高。但是在處理大數(shù)據(jù)集時,可能會影響性能,因為需要全表掃描和去重
2. GROUP BY
GROUP BY 用于將具有相同值的記錄分組,并可以進行聚合操作
即使不使用聚合函數(shù),僅使用 GROUP BY 也可以達到去重的效果
SELECT equipment_no FROM equipment_check_order GROUP BY equipment_no;
3. Mysql版本
3.1 低版本
在不支持窗口函數(shù)的 MySQL 版本中,可以使用子查詢來進行去重
假設希望去除 equipment_check_order 表中的重復 equipment_no,并保留每個 equipment_no 的最新記錄,可以使用子查詢的方式來實現(xiàn)
-- 創(chuàng)建目標表 CREATE TABLE IF NOT EXISTS deduplicated_orders ( equipment_no VARCHAR(255), check_date DATE, PRIMARY KEY (equipment_no, check_date) ); -- 將去重后的數(shù)據(jù)插入到目標表 INSERT INTO deduplicated_orders (equipment_no, check_date) SELECT equipment_no, check_date FROM equipment_check_order AS e WHERE check_date = ( SELECT MAX(check_date) FROM equipment_check_order WHERE equipment_no = e.equipment_no );
或者使用自聯(lián)拼接的方式:
-- 創(chuàng)建目標表 CREATE TABLE IF NOT EXISTS deduplicated_orders ( equipment_no VARCHAR(255), check_date DATE, PRIMARY KEY (equipment_no, check_date) ); -- 使用自聯(lián)接將去重后的數(shù)據(jù)插入到目標表 INSERT INTO deduplicated_orders (equipment_no, check_date) SELECT e1.equipment_no, e1.check_date FROM equipment_check_order e1 LEFT JOIN equipment_check_order e2 ON e1.equipment_no = e2.equipment_no AND e1.check_date < e2.check_date WHERE e2.check_date IS NULL;
3.2 高版本
使用 ROW_NUMBER() 和 WITH 子句進行去重
基本步驟:
- 定義公共表表達式(CTE): 使用 WITH 子句創(chuàng)建一個臨時結果集
- 應用 ROW_NUMBER() 函數(shù): 在 CTE 內(nèi)部為每一行分配唯一的行號
- 選擇需要的記錄: 在外層查詢中,根據(jù)行號篩選出需要的記錄
示例:保留每個 equipment_no 的最新記錄
假設有一個表 equipment_check_order,包含 equipment_no 和 check_date 列,希望去除重復的 equipment_no,并保留每個 equipment_no 的最新記錄(即 check_date 最大的記錄)
-- 創(chuàng)建目標表(如果不存在) CREATE TABLE IF NOT EXISTS deduplicated_orders ( equipment_no VARCHAR(255), check_date DATE, PRIMARY KEY (equipment_no, check_date) ); -- 使用 CTE 和 ROW_NUMBER() 進行去重 WITH ranked AS ( SELECT equipment_no, check_date, ROW_NUMBER() OVER (PARTITION BY equipment_no ORDER BY check_date DESC) AS rn FROM equipment_check_order ) INSERT INTO deduplicated_orders (equipment_no, check_date) SELECT equipment_no, check_date FROM ranked WHERE rn = 1;
- PARTITION BY equipment_no:根據(jù) equipment_no 列進行分組
- SELECT equipment_no, check_date FROM ranked WHERE rn = 1:從 CTE ranked 中選擇行號為 1 的記錄,即每個分組中最新的記錄,如果為小于5,代表去重并保留多條記錄
4. 總結
方法 | 用法示例 | 優(yōu)點 | 缺點 | 適用場景 |
---|---|---|---|---|
SELECT DISTINCT | SELECT DISTINCT equipment_no FROM equipment_check_order; | 簡單易用,直觀 | 對大數(shù)據(jù)集性能影響可能較大 | 單列去重,簡單查詢 |
GROUP BY | SELECT equipment_no FROM equipment_check_order GROUP BY equipment_no; | 靈活,與聚合函數(shù)結合使用方便 | 語法復雜,對性能影響與數(shù)據(jù)量有關 | 復雜查詢或需要與聚合函數(shù)結合使用的場景 |
子查詢 + ROW_NUMBER() | 高靈活性,可選擇特定記錄 | 需使用窗口函數(shù),語法復雜 | 高級去重,保留特定記錄 | |
臨時表 | 適合復雜數(shù)據(jù)處理,多步驟數(shù)據(jù)操作 | 操作步驟多,占用額外存儲空間 | 數(shù)據(jù)清理、遷移,復雜操作 |
以上就是MySQL實現(xiàn)去重的幾種方法小結的詳細內(nèi)容,更多關于MySQL去重的資料請關注腳本之家其它相關文章!
相關文章
mysql數(shù)據(jù)庫常見的優(yōu)化操作總結(經(jīng)驗分享)
這篇文章主要給大家介紹了關于mysql數(shù)據(jù)庫常見的優(yōu)化操作,文章總結的都是個人日常開發(fā)使用mysql數(shù)據(jù)庫的經(jīng)驗所得,其中包括Index索引、少用SELECT*、EXPLAIN SELECT以及開啟查詢緩存等相關資料,相信會對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。2017-04-04Linux中部署MySQL環(huán)境的四種方式圖文詳解
這篇文章主要介紹了Linux中部署MySQL環(huán)境的四種方式,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-11-11MySQL 8.0.13設置日期為0000-00-00 00:00:00時出現(xiàn)的問題解決
這篇文章主要介紹了MySQL 8.0.13設置日期為0000-00-00 00:00:00時出現(xiàn)的問題解決,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-01-01mysql 加了 skip-name-resolve不能鏈接數(shù)據(jù)庫問題的解決方法
這篇文章主要介紹了mysql 加了 skip-name-resolve不能鏈接數(shù)據(jù)庫問題的解決方法,需要的朋友可以參考下2016-04-04