Ba dòng cùng là một người: “nguyen an”, “Nguyen An ” và “NGUYEN AN”. COUNT DISTINCT của bạn đang đếm ba khách.
Bài toán
Cột ho_ten nhập tay từ ba nguồn khác nhau. Cùng một người xuất hiện ba kiểu, và mọi phép đếm đều sai.
Năm hàm giải quyết 90% trường hợp
| Hàm | Việc | Ví dụ |
|---|---|---|
TRIM | Cắt khoảng trắng hai đầu | TRIM(' an ') → 'an' |
UPPER / LOWER | Chuẩn hoá hoa thường | LOWER('AN') → 'an' |
CONCAT | Ghép chuỗi | CONCAT(ho,' ',ten) |
SUBSTRING | Cắt một đoạn | SUBSTRING(ma,1,3) |
REPLACE | Thay thế | REPLACE(sdt,'-','') |
SELECT
INITCAP(LOWER(TRIM(ho_ten))) AS ho_ten_sach,
COUNT(*)
FROM khach_hang
GROUP BY 1;
Lỗi thường gặp
1. CONCAT gặp NULL
-- MySQL: cả chuỗi thành NULL nếu ten_dem là NULL
SELECT CONCAT(ho, ' ', ten_dem, ' ', ten) FROM khach_hang;
-- An toàn
SELECT CONCAT_WS(' ', ho, ten_dem, ten) FROM khach_hang;
CONCAT_WS tự bỏ qua NULL. Trên PostgreSQL, toán tử || cũng biến cả chuỗi thành NULL — dùng COALESCE(ten_dem,'') để chặn.
2. Vị trí bắt đầu từ 1, không phải 0
SUBSTRING('ABCDEF', 1, 3) -- 'ABC'
SUBSTRING('ABCDEF', 0, 3) -- 'AB' (dễ nhầm)
3. Làm sạch trong WHERE là mất chỉ mục
-- Quét toàn bảng
WHERE LOWER(TRIM(email)) = 'an@gmail.com'
Nếu phải lọc thường xuyên như vậy, hãy làm sạch dữ liệu một lần khi nạp, hoặc tạo cột đã chuẩn hoá kèm chỉ mục riêng.
4. Cắt chuỗi có dấu tiếng Việt
LENGTH ở một số hệ trả về số byte, không phải số ký tự. Với UTF-8, “Nguyễn” có 6 ký tự nhưng 8 byte. Dùng CHAR_LENGTH khi bạn muốn đếm ký tự.
Tách chuỗi thành cột
-- Lấy tên miền từ email
SELECT SPLIT_PART(email, '@', 2) AS ten_mien -- PostgreSQL
SELECT SUBSTRING_INDEX(email, '@', -1) -- MySQL
FROM nguoi_dung;
Luyện tập
- LeetCode 1667 — Fix Names in a Table
- LeetCode 1484 — Group Sold Products By The Date
- LeetCode 1965 — Employees With Missing Information
- HackerRank — The Blunder (REPLACE và làm tròn)
- HackerRank — Name of Employees
Tóm lại
TRIM+LOWERgiải quyết phần lớn dữ liệu trùng do nhập tay.CONCATgặpNULLlàm hỏng cả chuỗi — dùngCONCAT_WS.- Vị trí trong
SUBSTRINGđếm từ 1. - Làm sạch trong
WHERElà mất chỉ mục; hãy làm sạch khi nạp dữ liệu. - Tiếng Việt có dấu: dùng
CHAR_LENGTH, không dùngLENGTH.
Bạn vừa học xong hàm xử lý chuỗi
Sẵn sàng luyện tập chưa?
Làm bài tập hàm xử lý chuỗi trên dữ liệu thật, chấm điểm ngay khi bạn bấm chạy.
Bắt đầu luyện tập →