2010-04-08 35 views
201

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

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

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

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

Trả lời

291

Khá đơn giản thực sự:

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

% là ký tự đại diện cho bất kỳ ký tự nào. Lưu ý rằng điều này có thể làm chậm trên các tập 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 phải sử dụng các chỉ mục toàn văn.

+0

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

+2

tôi biết về các truy vấn như thế nào, nhưng hôm nay tôi muốn tìm ra nếu giá trị nhất định tồn tại trong chuỗi trong một số cột tôi đã googling cho nó .. Tại sao tôi không bao giờ nghĩ về nó trước khi ?? –

+0

trường hợp này có nhạy cảm không? –

34
WHERE `column` LIKE '%$needle%' 
+0

khi tìm kiếm ký tự _ (gạch dưới) truy vấn LIKE '% _%' 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 _ – Wojtek

103

Sử dụng:

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

tham khảo:

+0

chắc chắn LIKE nhanh hơn INSTR? – oedo

+10

@oedo: Tùy 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; 'LIKE ...%' sẽ sử dụng 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. –

+0

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

8

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

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

Nếu bạn đang tìm kiếm một chuỗi bắt đầu với $needle của bạn:

... 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}' 
19

mỏ đang sử dụng LOCATE trong mysql:

LOCATE (substr, str), LOCATE (substr, str , pos)

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

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

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

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

-1

Có thể bạn đang tìm kiếm find_in_set chức năng:

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

Chức năng này hoạt động như in_array hàm trong PHP

2

phải nhận thức được rằng đâ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ể.

+6

* Một số cuộc tấn công có thể xảy ra. Ngoài ra, 'mysql_real_escape_string' sẽ không được chấp nhận trong các bản phát hành PHP trong tương lai. –

+0

điều cần biết :-) –

+7

Bạn nên sử dụng [báo cáo đã chuẩn bị] (http://au1.php.net/pdo.prepared-statements) và để thoát khỏi PHP. '$ stmt = $ dbh-> chuẩn bị (" Cột 'LIKE' LIKE '{: needle}' "); $ stmt-> bindParam (': kim', $ kim); $ stmt-> execute(); ' – cloudworks