Vấn đề
Cột Name chứa giá trị như '1stJohn (7)', '2ndSam (4)'. Cần xóa phần '(số)' ở cuối chuỗi.
Giải pháp: TRIM + SUBSTRING + CHAR_LENGTH + LOCATE + REVERSE
SELECT TRIM(SUBSTRING(Name, 1,
(CHAR_LENGTH(Name) - LOCATE('(', REVERSE(Name)))))
AS RemovingTrailingNumbers FROM DemoTable;
Ví dụ minh họa
Tạo bảng và chèn dữ liệu
mysql> CREATE TABLE DemoTable (Name VARCHAR(100));
mysql> INSERT INTO DemoTable VALUES
('1stJohn'), ('1stJohn (7)'), ('2ndSam'), ('2ndSam (4)');
Truy vấn
mysql> SELECT TRIM(SUBSTRING(Name, 1,
(CHAR_LENGTH(Name) - LOCATE('(', REVERSE(Name)))))
AS RemovingTrailingNumbers FROM DemoTable;
Kết quả
+-------------------------+ | RemovingTrailingNumbers | +-------------------------+ | 1stJohn | | 1stJohn | | 2ndSam | | 2ndSam | +-------------------------+
Phân tích công thức
REVERSE(Name): Đảo chuỗi. '1stJohn (7)' → '7) nhoJts1'.LOCATE('(', REVERSE(Name)): Tìm vị trí '(' trong chuỗi đảo → vị trí của ')' gốc từ cuối. Ví dụ: 2.CHAR_LENGTH(Name) - vị_trí: Độ dài phần cần giữ (trước '(').SUBSTRING(Name, 1, độ_dài): Lấy phần đầu.TRIM(): Xóa khoảng trắng dư (nếu có 'John (7) ').
Cách đơn giản hơn (MySQL 8.0+): REGEXP_REPLACE
SELECT REGEXP_REPLACE(Name, ' \\([0-9]+\\)$', '') FROM DemoTable;
- Regex:space + '(' + số + ')' + end-of-string.
- Thay bằng rỗng.
Cách dùng SUBSTRING_INDEX (nếu format cố định)
SELECT TRIM(SUBSTRING_INDEX(Name, ' (', 1)) FROM DemoTable;
Lấy phần trước ' (' đầu tiên. Nhanh và dễ hiểu hơn.
Lưu ý
- Công thức phức tạp dễ sai với edge case (không có '(', nhiều '(', NULL...).
- Luôn test kỹ với dữ liệu thực.
- Cân nhắc lưu tách cột: Name, SuffixNumber.