常見SQL去重方法
使用DISTINCT關鍵字去除重複行
適用於簡單列去重,直接作用於SELECT後的字段:
SELECT DISTINCT column1, column2 FROM table_name;
使用GROUP BY去重
通過分組實現去重,可結合聚合函數:
SELECT column1, MAX(column2)
FROM table_name
GROUP BY column1;
窗口函數去重(高級用法)
使用ROW_NUMBER()標記重複數據,適合複雜去重場景:
WITH deduplicated AS (
SELECT *,
ROW_NUMBER() OVER(PARTITION BY column1, column2 ORDER BY id) AS rn
FROM table_name
)
SELECT column1, column2
FROM deduplicated
WHERE rn = 1;
實際案例:用户訂單去重
場景:同一個用户同一天可能有多條訂單記錄,保留最新記錄:
WITH ranked_orders AS (
SELECT *,
ROW_NUMBER() OVER(PARTITION BY user_id, order_date ORDER BY create_time DESC) AS rank
FROM orders
)
SELECT * FROM ranked_orders WHERE rank = 1;
臨時表去重法
適合需要修改原表數據的場景:
CREATE TABLE temp_table AS
SELECT DISTINCT * FROM original_table;
TRUNCATE TABLE original_table;
INSERT INTO original_table
SELECT * FROM temp_table;
DROP TABLE temp_table;
劣勢
- 大數據量時
DISTINCT可能性能較差,優先考慮GROUP BY - 使用窗口函數時注意PARTITION BY的字段選擇
- 去重可能改變原有數據順序,需要時顯式添加ORDER BY
查詢重複
查找重複數據的基本方法
使用GROUP BY和HAVING子句可以快速識別重複記錄。以下示例基於特定列查找重複值:
SELECT column_name, COUNT(*)
FROM table_name
GROUP BY column_name
HAVING COUNT(*) > 1;
多列組合重複檢查
當需要檢查多個列的組合是否重複時,只需在GROUP BY中列出所有相關列:
SELECT column1, column2, COUNT(*)
FROM table_name
GROUP BY column1, column2
HAVING COUNT(*) > 1;
顯示完整重複記錄
要查看重複記錄的所有字段而不僅僅是統計信息,可以使用子查詢或窗口函數:
SELECT *
FROM table_name
WHERE column_name IN (
SELECT column_name
FROM table_name
GROUP BY column_name
HAVING COUNT(*) > 1
);
使用窗口函數的高級方法
ROW_NUMBER()函數能更靈活地處理重複數據,特別適合標記重複項:
SELECT *,
ROW_NUMBER() OVER(PARTITION BY column_name ORDER BY id) AS row_num
FROM table_name
刪除重複數據
保留單條記錄並刪除其他重複項的標準做法:
DELETE FROM table_name
WHERE id NOT IN (
SELECT MIN(id)
FROM table_name
GROUP BY column_name
);
臨時表處理大量重複數據
對於大型數據集,創建臨時表處理效率更高:
CREATE TABLE temp_table AS
SELECT DISTINCT * FROM original_table;
TRUNCATE TABLE original_table;
INSERT INTO original_table
SELECT * FROM temp_table;
DROP TABLE temp_table;
去重操作
數據庫去重方法
使用DISTINCT關鍵字 在SQL查詢中直接使用DISTINCT可以返回唯一值記錄:
SELECT DISTINCT column1, column2 FROM table_name;
GROUP BY分組去重 通過分組操作實現去重,可配合聚合函數使用:
SELECT column1, column2
FROM table_name
GROUP BY column1, column2;
窗口函數法(高級去重) 使用ROW_NUMBER()等窗口函數標記重複行後過濾:
WITH deduplicated AS (
SELECT *,
ROW_NUMBER() OVER(PARTITION BY column1, column2 ORDER BY id) AS rn
FROM table_name
)
SELECT * FROM deduplicated WHERE rn = 1;
編程語言去重方案
Python列表去重 使用集合特性或字典保持順序:
# 簡單去重
unique_list = list(set(original_list))
# 保持順序
unique_list = list(dict.fromkeys(original_list))
Pandas數據框去重 DataFrame提供多種去重方式:
# 基本去重
df.drop_duplicates(subset=['col1','col2'], keep='first')
# 條件去重
df.drop_duplicates(subset=['col1'], keep=False) # 刪除所有重複項
文件內容去重技術
Linux命令行去重 使用sort和uniq組合命令:
sort input_file.txt | uniq > output_file.txt
# 統計重複次數
sort input_file.txt | uniq -c
AWK高效處理 使用AWK實現快速去重:
awk '!seen[$0]++' input_file.txt > output_file.txt
大數據環境解決方案
Hive去重查詢 使用DISTRIBUTE BY和窗口函數:
SELECT * FROM (
SELECT *,
ROW_NUMBER() OVER(PARTITION BY key_column DISTRIBUTE BY key_column) as rn
FROM large_table
) t WHERE rn = 1;
Spark數據去重 通過DataFrame API處理:
df.dropDuplicates(['column1','column2'])
# 內存優化方式
df.distinct().write.mode('overwrite').parquet('output_path')
重複數據識別技巧
相似度匹配算法 對於文本類數據可使用以下方法:
from difflib import SequenceMatcher
def similarity(a, b):
return SequenceMatcher(None, a, b).ratio()
# 應用示例
[similarity(x,y) for x,y in zip(text_list1, text_list2)]
哈希值比對 生成數據指紋進行快速比對:
import hashlib
def get_hash(value):
return hashlib.md5(str(value).encode()).hexdigest()
# 創建哈希列用於比對
df['hash'] = df.apply(lambda row: get_hash(tuple(row)), axis=1)