常見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 BYHAVING子句可以快速識別重複記錄。以下示例基於特定列查找重複值:

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)