Tìm kiếm không dấu trong MySQL

Trong các cách tìm kiếm, thì người dùng thường tìm kiếm không dấu, vậy trong sqlserver tìm không dấu mình sẽ thực hiện như thế nào?

Chính vì vậy bài viết này, mình sẽ hướng dẫn các bạn cách tìm kiếm không dấu trong sqlserver.

Các bạn cũng có thể tham khảo thêm về full text search ở link bên dưới, tuy nhiên tùy vào trường hợp mà chúng ta sử dụng hay không? 

[SQLSERVER] Hướng dẫn sử dụng chức năng tìm kiếm Full Text Search SQL SERVER 2016

Dưới đây, mình có một bảng view nhân viên:

Khi chạy câu lệnh sql

SELECT manv, tennv, ngaysinh, tinhtrang, diachi1 FROM dbo.view_nhanvien

=> Kết quả dữ liệu bên dưới

Tìm kiếm không dấu trong MySQL

- Bây giờ, mình muốn tìm kiếm dữ liệu theo tennv, và các nhập truy vấn nhập vào có dấu hay không dấu đều trả về dữ liệu cho chúng ta.

Thông thường, khi nhận 1 yêu cầu chức năng tìm kiếm không chính xác bạn sẽ nghĩ ngay đến câu query sau:
SELECT id,title,description FROM book WHERE title LIKE ‘%keyword%’

Nhưng nó có 1 số hạn chế: không chính xác, tốc độ truy vấn chậm, vấn đề với tiếng Việt có dấu và không có dấu.

nhoemzx

16-01-2012, 15:55

cái bạn nói mình chưa tìm hiểu.
Nhưng search thì có 3 cách cơ bản.
=> lưu 1 cột không dấu nữa
=> bỏ dấu lúc select ở mệnh đề WHERE
=> Thêm dấu cho từ bạn nhập rồi LIKE,
Nếu tìm kiếm không nhiều thì cách 3 là hay nhất :D

2 cách đầu tiên thì sẽ phải đi cùng với nhau, và mình không muốn để cập vì có thể chiển khai, nhưng như đã nói, làm như vậy sẽ bị data redundancy, và đi ngược lại cấu trúc logic của database.

Thêm dấu cho từ bạn nhập rồi LIKE <--- bạn đã thực sự triển khai cách này, nếu có, thì có thể share kết quả được không.

Mình mới làm xong function search bằng regular expression, mới test qua cũng khá triển vọng, tối về mình sẽ post chi tiết hơn. Ví dụ:

data trong table:
+ Em Sẽ Là Người Ra Đi

Các string khi search sẽ trả về kết quả:
+em se la nguoi ra di (1 phần của string cũng sẽ có kết quả, e.g.: em se, nguoi ra or nguoi ra di, nhưng ít nhất 2 từ, mình có thể specify bao nhiêu từ thì bắt đầu trả về kết quả, 1 từ cũng được nhưng như vậy sẽ too ambiguous).
+em sẽ là nguoi ra di (vừa tiếng viết không dấu, có dấu).
+ em sẽ là người ra đii (100% tiếng việt)
+em sé la ngươi ra đi (tiếng việt có dấu, nhưng sai chính tả, cũng khá phổ biến với đại đa số người dùng).

Ở bài tìm hiểu lệnh SELECT mình đã liệt kê danh sách các toán tử và trong đó có hai toán tử là INLIKE thì trong bài này chúng ta sẽ tìm hiểu nó. Về cách sử dụng thì INLIKE rất hữu dụng nhưng về thực tế thì chúng ta cần phải xem lại nó. Chi tiết thến ào thì chúng ta sẽ tìm hiểu nó nhé.

Tìm kiếm không dấu trong MySQL

Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Nhưng trước tiên chúng ta cần tạo Database, tạo Table và insert vài dòng dữ liệu đã nhé:

CREATE DATABASE IF NOT EXISTS qlsv;
USE qlsv;
 
CREATE TABLE IF NOT EXISTS sinhvien(
    sv_id INT(11) NOT NULL AUTO_INCREMENT,
    sv_name VARCHAR(255) NOT NULL,
    sv_description  VARCHAR(500),
    CONSTRAINT pk_sinhvien PRIMARY KEY(sv_id)
) ENGINE = INNODB;
 
INSERT INTO sinhvien(sv_name, sv_description)
VALUES('Mr Cuong', 'Nguyen Van Cuong');
 
INSERT INTO sinhvien(sv_name, sv_description)
VALUES('Mr Kinh', 'Nguyen Van Kinh');
 
INSERT INTO sinhvien(sv_name, sv_description)
VALUES('Mr Chinh', 'Nguyen Van Chinh');
 
INSERT INTO sinhvien(sv_name, sv_description)
VALUES('Mr Quyen', 'Nguyen Van Quyen');

Bài viết này được đăng tại [free tuts .net]

Kết quả:

Tìm kiếm không dấu trong MySQL

Chúng ta sẽ sử dụng dữ liệu này để truy vấn cho các demo luôn nhé.

1. WHERE IN trong MySQL

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE sv_name IN ('Mr Cuong', 'Mr Kinh', 'Mr Chinh')
0 có tác dụng tương tự như hàm trong PHP vậy, nghĩa là sẽ kiểm tra giá trị của field đó có nằm trong một tập hợp nào đó hay không. Chẳng hạn bạn cần kiểm tra trong bảng sinh viên có sinh viên nào có tên là
SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE sv_name IN ('Mr Cuong', 'Mr Kinh', 'Mr Chinh')
1,
SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE sv_name IN ('Mr Cuong', 'Mr Kinh', 'Mr Chinh')
2 hoặc
SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE sv_name IN ('Mr Cuong', 'Mr Kinh', 'Mr Chinh')
3 hay không? thì ta sẽ tạo điều kiện IN như sau:

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE sv_name IN ('Mr Cuong', 'Mr Kinh', 'Mr Chinh')

Kết quả sẽ là:

Tìm kiếm không dấu trong MySQL

Như vậy những record nào có tên là

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE sv_name IN ('Mr Cuong', 'Mr Kinh', 'Mr Chinh')
5 hoặc
SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE sv_name IN ('Mr Cuong', 'Mr Kinh', 'Mr Chinh')
6 hoặc
SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE sv_name IN ('Mr Cuong', 'Mr Kinh', 'Mr Chinh')
7 thì đều được chọn.

Nếu không sử dụng IN thì ta sẽ dùng toán tử

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE sv_name IN ('Mr Cuong', 'Mr Kinh', 'Mr Chinh')
9 để tạo điều kiện. Như ví dụ trên tôi sẽ chuyển sang sử dụng OR như sau:

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE 
	sv_name = 'Mr Cuong' OR
	sv_name = 'Mr Kinh' OR	
	sv_name = 'Mr Chinh'	

2. WHERE LIKE trong MySQL

Like dịch trong tiếng anh có nghĩa là giống, trong ngôn ngữ

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE 
	sv_name = 'Mr Cuong' OR
	sv_name = 'Mr Kinh' OR	
	sv_name = 'Mr Chinh'	
0 thì nó cũng có ý nghĩa tương tự đó là tìm những dòng nào mà có dữ liệu giống với cấu trúc lệnh LIKE truyền vào. Nó hoạt động theo nguyên tắc tương tự như Regular Expression vậy, nghĩa là sẽ so khớp với cấu trúc của chuỗi LIKE truyền vào. Sau đây là một số ví dụ liên quan tới lệnh LIKE trong
SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE 
	sv_name = 'Mr Cuong' OR
	sv_name = 'Mr Kinh' OR	
	sv_name = 'Mr Chinh'	
4.

LIKE với ký hiệu %

Ký hiệu % sẽ đại diện cho 0 hoặc nhiều ký tự.

Ví dụ: cần tìm những sinh viên nào có tên và trong tên chỉ cần có chữ

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE 
	sv_name = 'Mr Cuong' OR
	sv_name = 'Mr Kinh' OR	
	sv_name = 'Mr Chinh'	
5 là được chọn.

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE sv_name LIKE '%Cuong%'

Kết quả nó sẽ trả về một record duy nhất. Riêng với chuỗi

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE 
	sv_name = 'Mr Cuong' OR
	sv_name = 'Mr Kinh' OR	
	sv_name = 'Mr Chinh'	
6 thì tôi sẽ giải thích cho các trường hợp sau là đúng:

  • Chuỗi 'some thing Cuong some thing' đúng
  • Chuỗi 'some thing Cuong' đúng
  • Chuỗi 'Cuong some thing' đúng

Ví dụ: Tìm những sinh viên nào có lastname là Kinh

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE sv_name LIKE '%Kinh'

Có lẽ bạn thắc mắc tại sao lại chỉ có mỗi dấu

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE 
	sv_name = 'Mr Cuong' OR
	sv_name = 'Mr Kinh' OR	
	sv_name = 'Mr Chinh'	
7 ở đằng trước nhỉ
Tìm kiếm không dấu trong MySQL
Lý do đơn giản bởi vì lastname thì ở cuối của chuỗi rồi cho nên đằng sau lastname sẽ không có gì nữa, còn đằng trước thì là các chữ cái bất kì

Like với kí hiệu _

Ký hiệu

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE 
	sv_name = 'Mr Cuong' OR
	sv_name = 'Mr Kinh' OR	
	sv_name = 'Mr Chinh'	
8 đại diện cho một ký tự bất kì, nghĩa là khi bạn sử dụng ký hiệu này thì nó sẽ là một ký tự thay vì 0 hoặc nhiều ký tự như ký hiệu
SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE 
	sv_name = 'Mr Cuong' OR
	sv_name = 'Mr Kinh' OR	
	sv_name = 'Mr Chinh'	
7.

Ví dụ: Tìm sinh viên có tên bắt đầu chữ M, ký tự thứ 2 bất kì và tiếp theo là khoảng trắng, tiếp theo nữa là các ký tự bất kì

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE sv_name LIKE 'M_ %'

Cú pháp

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE sv_name LIKE '%Cuong%'
0 có ý nghĩa là bắt đầu chữ M, tiếp theo là dấu
SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE 
	sv_name = 'Mr Cuong' OR
	sv_name = 'Mr Kinh' OR	
	sv_name = 'Mr Chinh'	
8 nên nó là ký tự bất kì, tiếp theo là khoảng trắng và tiếp nữa dấu % là 0 hoặc nhiều ký tự bất kì.

Còn khá nhiều nữa nhưng thông thường chúng ta sử dụng hai ký hiệu

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE 
	sv_name = 'Mr Cuong' OR
	sv_name = 'Mr Kinh' OR	
	sv_name = 'Mr Chinh'	
7 và
SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE 
	sv_name = 'Mr Cuong' OR
	sv_name = 'Mr Kinh' OR	
	sv_name = 'Mr Chinh'	
8 thôi nên mình sẽ không trình bày thêm để tránh độ phức tạp ở đây. Nếu bạn muốn tìm hiểu có thể vào để tham khảo.

# Lời kết

Nhìn sơ qua thì thấy nó hay nhưng tính đến sự tối ưu thì hai lệnh này sẽ gây mất khá nhiều thời gian để so khớp, chính vì vậy khi làm ứng dụng website lớn bạn nên hạn chế sử dụng lệnh LIKEIN nhé, thay vào đó bạn sẽ tìm hiểu một kỹ thuật cao hơn đó là

SELECT sv_id, sv_name, sv_description
FROM SINHVIEN
WHERE sv_name LIKE '%Cuong%'
6.