SQL - 處理重複資料:初學者指南

你好,未來的SQL大師!今天,我們將要進入處理SQL中重複資料的迷人世界。別擔心如果你之前從未寫過一行代碼——我會成為你這次旅程中的友好導師,我們將一步一步地學習。到了這個教學的結尾,你將會像專家一樣處理重複資料!

SQL - Handling Duplicates

為什麼在SQL中處理重複資料是必要的?

想像你正在籌備一個派對,你有一份賓客名單。你肯定不希望同一個人被列兩次,對吧?這就是為什麼在SQL中處理重複資料如此重要的原因。在數據庫的世界裡,重複的數據可能會導致各種問題:

  1. 浪費存儲空間
  2. 可能導致計算和報告不正確
  3. 使得數據維護更加困難

讓我分享一個快速的故事。在我擔任數據庫管理員的初期,我曾在客戶數據庫中忽略了某些重複的資料。結果如何呢?我們的市場營銷團隊給一些客戶發送了多封促銷郵件。不難想像,那些客戶並不高興,而我也是從痛苦的經驗中學到了教訓!

防止重複條目

處理重複資料的最佳方式是從一開始就阻止它們進入你的數據庫。以下是一些達到此目的的方法:

1. 使用主鍵

主鍵是一個列(或列的組合),它唯一地標識表中的每一行。根據定義,它不能包含重複。

CREATE TABLE Students (
StudentID INT PRIMARY KEY,
FirstName VARCHAR(50),
LastName VARCHAR(50)
);

在這個例子中,StudentID 是我們的主鍵。SQL 將自動防止任何重複的 StudentID 值被插入。

2. 使用唯一約束

唯一約束與主鍵相似,但它可以應用於不是主鍵的列。

CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
Email VARCHAR(100) UNIQUE,
FirstName VARCHAR(50),
LastName VARCHAR(50)
);

在這裡,我們為 Email 列添加了一個唯一約束。這保證了沒有兩個員工可以擁有相同的電子郵件地址。

3. 使用 INSERT IGNORE

如果你使用的是 MySQL,你可以使用 INSERT IGNORE 語句來默默地忽略重複條目:

INSERT IGNORE INTO Students (StudentID, FirstName, LastName)
VALUES (1, 'John', 'Doe');

如果已經存在一個 StudentID 為 1 的學生,這個語句不會抛出錯誤——它將簡單地忽略重複條目。

計算和識別重複

有時候,即使我們盡了最大努力,重複資料還是會悄悄進入我們的數據。讓我們學習如何找到它們!

計算重複

要計算重複,我們可以使用 GROUP BY 語句以及 HAVING 語句:

SELECT FirstName, LastName, COUNT(*) as Count
FROM Students
GROUP BY FirstName, LastName
HAVING Count > 1;

這個查詢將學生按他們的名字進行分組,然後只顯示有超過一個條目的組。這就像在問,“給我顯示所有出現超過一次的名字,以及它們出現的次數。”

識別特定的重複

要查看實際的重複行,我們可以使用自連接:

SELECT s1.*
FROM Students s1
JOIN Students s2 ON
s1.FirstName = s2.FirstName AND
s1.LastName = s2.LastName AND
s1.StudentID > s2.StudentID;

這個查詢將每個學生記錄與其他每個學生記錄進行比較。如果它找到兩個具有相同名字但不同ID的記錄,它將顯示具有較高ID的記錄。這就像在說,“給我顯示所有與其他學生名字相同的學生,但只顯示ID號碼較高的那一個。”

從表中刪除重複

現在我們已經找到了我們的重複資料,讓我們來清理它們!

1. 使用 DISTINCT

DISTINCT 關鍵字是最簡單的從查詢結果中移除重複的方法:

SELECT DISTINCT FirstName, LastName
FROM Students;

這個查詢將顯示每個獨特的名字組合,無論它在表中出現多少次。

2. 使用 GROUP BY

GROUP BY 也可以用來移除重複:

SELECT FirstName, LastName
FROM Students
GROUP BY FirstName, LastName;

這個查詢給出與 DISTINCT 相同的結果,但當你需要進行聚合函數時它可以更靈活。

3. 永久刪除重複

如果你需要從你的表中實際刪除重複行,你可以使用子查詢:

DELETE s1 FROM Students s1
INNER JOIN Students s2
WHERE
s1.FirstName = s2.FirstName AND
s1.LastName = s2.LastName AND
s1.StudentID > s2.StudentID;

這個查詢刪除所有的重複學生,只保留 StudentID 最小的那一個。請非常小心使用這個語句——在SQL中沒有撤銷按鈕!

這裡是一個總結我們討論過的方法的表格:

方法 使用案例 示例
主鍵 防止重複 CREATE TABLE Students (StudentID INT PRIMARY KEY, ...);
唯一約束 在特定列中防止重複 CREATE TABLE Employees (Email VARCHAR(100) UNIQUE, ...);
INSERT IGNORE 靜默忽略重複(MySQL) INSERT IGNORE INTO Students ...
COUNT(*) 與 GROUP BY 計算重複 SELECT ..., COUNT(*) ... GROUP BY ... HAVING Count > 1;
自連接 識別特定重複 SELECT s1.* FROM Students s1 JOIN Students s2 ON ...
DISTINCT 從查詢結果中移除重複 SELECT DISTINCT FirstName, LastName FROM Students;
DELETE 與自連接 永久移除重複 DELETE s1 FROM Students s1 INNER JOIN Students s2 WHERE ...

就这样!你现在已经装备了像经验丰富的SQL专家一样处理重复数据的知识。记住,能力越大,责任越大——在运行删除数据的查询之前,总是要双倍检查你的查询。快乐编码,愿你的数据库永远无重复数据!

Credits: Image by storyset