SQL - 處理重複資料:初學者指南
你好,未來的SQL大師!今天,我們將要進入處理SQL中重複資料的迷人世界。別擔心如果你之前從未寫過一行代碼——我會成為你這次旅程中的友好導師,我們將一步一步地學習。到了這個教學的結尾,你將會像專家一樣處理重複資料!
為什麼在SQL中處理重複資料是必要的?
想像你正在籌備一個派對,你有一份賓客名單。你肯定不希望同一個人被列兩次,對吧?這就是為什麼在SQL中處理重複資料如此重要的原因。在數據庫的世界裡,重複的數據可能會導致各種問題:
- 浪費存儲空間
- 可能導致計算和報告不正確
- 使得數據維護更加困難
讓我分享一個快速的故事。在我擔任數據庫管理員的初期,我曾在客戶數據庫中忽略了某些重複的資料。結果如何呢?我們的市場營銷團隊給一些客戶發送了多封促銷郵件。不難想像,那些客戶並不高興,而我也是從痛苦的經驗中學到了教訓!
防止重複條目
處理重複資料的最佳方式是從一開始就阻止它們進入你的數據庫。以下是一些達到此目的的方法:
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