SQL - Xử lý Trùng Lặp: Hướng dẫn cho Người Mới Bắt Đầu

Xin chào các bạn tương lai trở thành phù thủy SQL! Hôm nay, chúng ta sẽ cùng khám phá thế giới fascinante của việc xử lý trùng lặp trong SQL. Đừng lo lắng nếu bạn chưa bao giờ viết một dòng mã trước đây - tôi sẽ là người bạn đồng hành thân thiện của bạn trong hành trình này, và chúng ta sẽ cùng nhau bước từng bước. Cuối cùng của bài hướng dẫn này, bạn sẽ xử lý trùng lặp như một chuyên gia!

SQL - Handling Duplicates

Tại sao Xử lý Trùng Lặp trong SQL lại Quan trọng?

Hãy tưởng tượng bạn đang tổ chức một bữa tiệc và bạn có một danh sách khách. Bạn không muốn một người xuất hiện hai lần, phải không? Đó chính xác là lý do tại sao việc xử lý trùng lặp trong SQL lại quan trọng. Trong thế giới cơ sở dữ liệu, dữ liệu trùng lặp có thể gây ra nhiều vấn đề:

  1. Nó lãng phí không gian lưu trữ
  2. Nó có thể dẫn đến các phép toán và báo cáo không chính xác
  3. Nó làm cho việc bảo trì dữ liệu trở nên khó khăn hơn

Hãy để tôi chia sẻ một câu chuyện nhanh. Trong những ngày đầu tiên làm quản trị viên cơ sở dữ liệu, tôi đã bỏ qua một số trùng lặp trong cơ sở dữ liệu khách hàng. Kết quả? Đội ngũ tiếp thị của chúng tôi đã gửi cùng một email khuyến mãi cho một số khách hàng nhiều lần. Cần nói thêm rằng, những khách hàng đó không hề vui vẻ, và tôi đã học bài học một cách khó khăn!

Ngăn Chặn Các Trùng Lặp

Cách tốt nhất để xử lý trùng lặp là ngăn chặn chúng không cho vào cơ sở dữ liệu của bạn từ đầu. Dưới đây là một số phương pháp để đạt được điều này:

1. Sử dụng Khóa Chính (Primary Key)

Khóa chính là một cột (hoặc sự kết hợp của các cột) giúp xác định duy nhất mỗi hàng trong bảng. Theo định nghĩa, nó không thể chứa trùng lặp.

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

Trong ví dụ này, StudentID là khóa chính của chúng tôi. SQL sẽ tự động ngăn chặn bất kỳ giá trị trùng lặp nào của StudentID từ việc được chèn vào.

2. Sử dụng Ràng Buộc Độc Đáo (Unique Constraint)

Ràng buộc độc đáo tương tự như khóa chính nhưng có thể được áp dụng cho các cột không phải là khóa chính.

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

Ở đây, chúng tôi đã thêm một ràng buộc độc đáo vào cột Email. Điều này đảm bảo rằng không có hai nhân viên nào có thể có cùng địa chỉ email.

3. Sử dụng INSERT IGNORE

Nếu bạn đang sử dụng MySQL, bạn có thể sử dụng lệnh INSERT IGNORE để im lặng bỏ qua các mục trùng lặp:

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

Nếu đã có một sinh viên với StudentID 1, lệnh này sẽ không gây ra lỗi - nó sẽ đơn giản bỏ qua mục trùng lặp.

Đếm và Xác Định Trùng Lặp

Đôi khi, trùng lặp vẫn lọt vào dữ liệu mặc dù chúng ta đã cố gắng hết sức. Hãy học cách tìm chúng!

Đếm Trùng Lặp

Để đếm trùng lặp, chúng ta có thể sử dụng cụm từ GROUP BY cùng với cụm từ HAVING:

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

Truy vấn này nhóm sinh viên theo tên đầu tiên và tên cuối, sau đó hiển thị chỉ các nhóm có hơn một mục. Nó giống như hỏi, "Hiển thị cho tôi tất cả các tên xuất hiện hơn một lần và số lần chúng xuất hiện."

Xác Định Các Trùng Lặp Cụ Thể

Để xem các hàng trùng lặp thực tế, chúng ta có thể sử dụng một tự join:

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

Truy vấn này so sánh mỗi mục sinh viên với mọi mục sinh viên khác. Nếu nó tìm thấy hai mục có cùng tên nhưng ID khác nhau, nó sẽ hiển thị mục có ID cao hơn. Nó giống như nói, "Hiển thị cho tôi tất cả các sinh viên có cùng tên với một sinh viên khác, nhưng chỉ hiển thị sinh viên có số ID cao hơn."

Loại Bỏ Trùng Lặp khỏi Bảng

Bây giờ chúng ta đã tìm thấy trùng lặp, hãy làm sạch chúng!

1. Sử dụng DISTINCT

Từ khóa DISTINCT là cách đơn giản nhất để loại bỏ trùng lặp khỏi kết quả truy vấn:

SELECT DISTINCT FirstName, LastName
FROM Students;

Truy vấn này sẽ hiển thị mỗi sự kết hợp duy nhất của tên đầu tiên và tên cuối, bất kể nó xuất hiện bao nhiêu lần trong bảng.

2. Sử dụng GROUP BY

GROUP BY cũng có thể được sử dụng để loại bỏ trùng lặp:

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

Truy vấn này cho kết quả tương tự như DISTINCT, nhưng nó có thể linh hoạt hơn khi bạn cần thực hiện các hàm tổng hợp.

3. Loại Bỏ Trùng Lặp Vĩnh Viễn

Nếu bạn cần xóa các hàng trùng lặp khỏi bảng của bạn, bạn có thể sử dụng một subquery:

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

Truy vấn này xóa tất cả các sinh viên trùng lặp, giữ lại chỉ một sinh viên có StudentID thấp nhất. Hãy rất cẩn thận với truy vấn này - không có nút Undo trong SQL!

Dưới đây là bảng tóm tắt các phương pháp chúng ta đã thảo luận:

Phương pháp Trường hợp sử dụng Ví dụ
Khóa Chính (Primary Key) Ngăn chặn trùng lặp CREATE TABLE Students (StudentID INT PRIMARY KEY, ...);
Ràng Buộc Độc Đáo (Unique Constraint) Ngăn chặn trùng lặp trong các cột cụ thể CREATE TABLE Employees (Email VARCHAR(100) UNIQUE, ...);
INSERT IGNORE Im lặng bỏ qua trùng lặp (MySQL) INSERT IGNORE INTO Students ...
COUNT(*) với GROUP BY Đếm trùng lặp SELECT ..., COUNT(*) ... GROUP BY ... HAVING Count > 1;
Tự Join Xác định trùng lặp cụ thể SELECT s1.* FROM Students s1 JOIN Students s2 ON ...
DISTINCT Loại bỏ trùng lặp khỏi kết quả truy vấn SELECT DISTINCT FirstName, LastName FROM Students;
DELETE với Tự Join Loại bỏ trùng lặp vĩnh viễn DELETE s1 FROM Students s1 INNER JOIN Students s2 WHERE ...

Và đó là tất cả! Bây giờ bạn đã được trang bị kiến thức để xử lý trùng lặp như một chuyên gia SQL. Nhớ rằng, với quyền lực lớn đi kèm với trách nhiệm lớn - luôn kiểm tra kỹ lưỡng các truy vấn của bạn trước khi chạy chúng, đặc biệt là khi xóa dữ liệu. Chúc bạn may mắn và dữ liệu của bạn luôn không có trùng lặp!

Credits: Image by storyset