Chuỗi truy vấn MySQL chứa


307

Tôi đã cố gắng tìm hiểu làm thế nào tôi có thể thực hiện một truy vấn với MySQL để kiểm tra xem giá trị (chuỗi $haystack) trong một cột nhất định có chứa dữ liệu nhất định (chuỗi $needle) không, như sau:

mysql_query("
SELECT *
FROM `table`
WHERE `column`.contains('{$needle}')
");

Trong PHP, hàm được gọi substr($haystack, $needle), vì vậy có thể:

WHERE substr(`column`, '{$needle}')=1

Câu trả lời:


437

Thực sự khá đơn giản:

mysql_query("
SELECT *
FROM `table`
WHERE `column` LIKE '%{$needle}%'
");

Đây %là ký tự đại diện cho bất kỳ ký tự nào được đặt (không có, một hoặc nhiều). Xin lưu ý rằng điều này có thể bị chậm trên các bộ dữ liệu rất lớn vì vậy nếu cơ sở dữ liệu của bạn phát triển, bạn sẽ cần sử dụng các chỉ mục fulltext.


1
Điều này sẽ chỉ hoạt động nếu bạn sử dụng một truy vấn chuẩn bị. Nếu bạn đang sử dụng một chuỗi thực tế trong đó (ví dụ: tập lệnh nâng cấp sql lỏng), hãy xem xét INSTR được đề cập bên dưới). Điều này là do nếu chuỗi của bạn chứa% thì bạn sẽ bắt đầu khớp mọi thứ với chuỗi đó.
Ryan Shillington

2
Tôi biết về các truy vấn như thế, nhưng hôm nay tôi muốn tìm hiểu xem giá trị nào đó có tồn tại trong chuỗi trong một số cột tôi đang tìm kiếm nó không .. Tại sao tôi chưa bao giờ nghĩ về nó trước đây ??
Mã nóng bỏng

1
trường hợp này có nhạy cảm không?
kiwi tức giận

2
@angry_kiwi: với column LIKE '...'trường hợp không nhạy cảm, với column LIKE BINARY '...'trường hợp nhạy cảm
Wolph

2
Tôi ngạc nhiên khi LIKEđề xuất kiểm tra bất kỳ chuỗi con nào vì toán tử này sử dụng hai ký tự đại diện: %_. Điều này có nghĩa là nếu chuỗi $ kim của bạn chứa một trong các ký tự đặc biệt này thì kết quả không như mong đợi. (-1) cho câu trả lời này và (+1) cho câu trả lời INSTR.
Skrol29

144

Sử dụng:

SELECT *
  FROM `table`
 WHERE INSTR(`column`, '{$needle}') > 0

Tài liệu tham khảo:


chắc chắn THÍCH nhanh hơn INSTR?
chris

17
@oedo: Phụ thuộc. LIKE %...%sẽ không sử dụng chỉ mục nếu có, vì vậy chúng phải tương đương nhau; LIKE ...%sẽ sử dụng một chỉ mục nếu có. Nếu hiệu suất là một mối quan tâm thực sự, Tìm kiếm toàn văn bản (FTS) sẽ là một cách tiếp cận tốt hơn.
OMG Ponies

hoàn hảo. chỉ là những gì tôi đã tìm kiếm.
arik

2
Tôi thích giải pháp này vì trên thực tế không có cách nào để sắp xếp mọi thứ theo sự hiện diện của một chuỗi con với liketoán tử. Với instrmột cụm từ có thể được đặt hàng như thế nàyselect * from table order by instr(col1,"mystring")
Radacina

Tôi muốn tìm kiếm _ trong một lĩnh vực và nó đã hoạt động. Cảm ơn
Ahmed

53
WHERE `column` LIKE '%$needle%'

2
khi tìm kiếm ký tự _ (gạch dưới), truy vấn THÍCH '% _%' không hoạt động, vì một số lý do, nó trả về tất cả các chuỗi ngay cả khi không có _
Wojtek

1
@Wojtek _ là ký tự đại diện cho bất kỳ ký tự đơn nào, vì vậy nếu bạn muốn tìm kiếm một dấu gạch dưới theo nghĩa đen, bạn sẽ cần phải thoát nó. Xem truy vấn MySQL THÍCH với dấu gạch dưới .
jkmartindale

29

Của tôi đang sử dụng LOCATEtrong mysql:

VỊ TRÍ (đế, str), VỊ TRÍ (đế, str, pos)

Hàm này an toàn nhiều byte và chỉ phân biệt chữ hoa chữ thường nếu có ít nhất một đối số là một chuỗi nhị phân.

Trong trường hợp của bạn:

mysql_query("
SELECT * FROM `table`
WHERE LOCATE('{$needle}','column') > 0
");

11
'cột' phải là cột (không có dấu ngoặc kép)
Wojtek

10

Ngoài câu trả lời từ @WoLpH.

Khi sử dụng LIKEtừ khóa, bạn cũng có khả năng giới hạn hướng phù hợp với chuỗi. Ví dụ:

Nếu bạn đang tìm kiếm một chuỗi bắt đầu bằng $needle:

... WHERE column LIKE '{$needle}%'

Nếu bạn đang tìm kiếm một chuỗi kết thúc bằng $needle:

... WHERE column LIKE '%{$needle}'

3

lưu ý rằng điều này là nguy hiểm:

WHERE `column` LIKE '%{$needle}%'

Làm đầu tiên:

$needle = mysql_real_escape_string($needle);

vì vậy nó sẽ ngăn chặn các cuộc tấn công có thể.


7
* Một số cuộc tấn công có thể. Ngoài ra, mysql_real_escape_stringsẽ bị phản đối trong các bản phát hành PHP trong tương lai.
Jack Tuck

11
Bạn nên sử dụng các câu lệnh đã chuẩn bị và để lại lối thoát cho PHP. $stmt = $dbh->prepare("Where 'column' LIKE '{:needle}'"); $stmt->bindParam(':needle', $needle); $stmt->execute();
đám mây ngày

3

Bạn có thể đang tìm kiếm find_in_setchức năng:

Where find_in_set($needle,'column') > 0

Hàm này hoạt động giống như in_arrayhàm trong PHP

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.