String kueri MySQL berisi


307

Saya sudah mencoba mencari tahu bagaimana saya bisa membuat kueri dengan MySQL yang memeriksa apakah nilai (string $haystack) di kolom tertentu berisi data (string $needle) tertentu, seperti ini:

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

Di PHP, fungsinya dipanggil substr($haystack, $needle), jadi mungkin:

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

Jawaban:


437

Sebenarnya cukup sederhana:

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

Ini %adalah wildcard untuk set karakter apa pun (tidak ada, satu atau banyak). Perhatikan bahwa ini bisa lambat pada kumpulan data yang sangat besar sehingga jika basis data Anda tumbuh Anda harus menggunakan indeks teks lengkap.


1
Ini hanya akan berfungsi jika Anda menggunakan kueri yang disiapkan. Jika Anda menggunakan string aktual di sana (mis. Skrip peningkatan sql liquibase) maka pertimbangkan INSTR yang disebutkan di bawah ini). Ini karena jika string Anda berisi% maka Anda akan mulai mencocokkan sesuatu dengannya.
Ryan Shillington

2
saya tahu tentang pertanyaan seperti, namun hari ini saya ingin mencari tahu apakah ada nilai tertentu dalam string di beberapa kolom saya googling untuk itu .. Mengapa saya tidak pernah memikirkannya sebelumnya ??
Sizzling Code

1
apakah case ini sensitif?
Kiwi

2
@angry_kiwi: dengan column LIKE '...'itu peka huruf besar kecil, dengan column LIKE BINARY '...'itu peka huruf besar kecil
Wolph

2
Saya terkejut bahwa LIKEdiusulkan untuk memeriksa substring karena operator ini menggunakan dua karakter wildcard: %dan _. Ini berarti jika string $ jarum Anda mengandung salah satu karakter khusus ini maka hasilnya tidak seperti yang diharapkan sama sekali. (-1) untuk balasan ini, dan (+1) untuk balasan INSTR.
Skrol29

144

Menggunakan:

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

Referensi:


pasti LIKE lebih cepat daripada INSTR?
chris

17
@ Oedo: Tergantung. LIKE %...%tidak akan menggunakan indeks jika ada, jadi mereka harus setara; LIKE ...%akan menggunakan indeks jika ada. Jika kinerja adalah masalah nyata, Pencarian Teks Lengkap (FTS) akan menjadi pendekatan yang lebih baik.
OMG Ponies

sempurna. apa yang saya cari.
arik

2
Saya suka solusi ini karena sebenarnya tidak ada cara untuk mengurutkan hal-hal sesuai dengan kehadiran substring dengan likeoperator. Dengan instrfrasa dapat dipesan seperti iniselect * from table order by instr(col1,"mystring")
Radacina

Saya ingin mencari _ di bidang dan itu berhasil. Terima kasih
Safeer Ahmed

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

2
saat mencari karakter _ (garis bawah) kueri SEPERTI '% _%' tidak berfungsi, untuk beberapa alasan ia mengembalikan semua string bahkan tanpa _
Wojtek

1
@Wojtek _ adalah wildcard untuk setiap karakter tunggal, jadi jika Anda ingin mencari garis bawah literal, Anda harus menghindarinya. Lihat permintaan MySQL LIKE dengan garis bawah .
jkmartindale

29

Tambang menggunakan LOCATEdi mysql:

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

Fungsi ini multi-byte aman, dan case-sensitive hanya jika setidaknya satu argumen adalah string biner.

Dalam kasus Anda:

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

11
'kolom' harus berupa kolom (tanpa tanda kutip)
Wojtek

10

Selain jawaban dari @WoLpH.

Saat menggunakan LIKEkata kunci, Anda juga memiliki kemampuan untuk membatasi arah string yang cocok. Sebagai contoh:

Jika Anda mencari string yang dimulai dengan $needle:

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

Jika Anda mencari string yang diakhiri dengan $needle:

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

3

Ketahuilah bahwa ini berbahaya:

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

lakukan dulu:

$needle = mysql_real_escape_string($needle);

jadi itu akan mencegah kemungkinan serangan.


7
* Beberapa kemungkinan serangan. Juga, mysql_real_escape_stringakan ditinggalkan dalam rilis PHP masa depan.
Jack Tuck

11
Anda harus menggunakan pernyataan yang sudah disiapkan , dan meninggalkan escaping ke PHP. $stmt = $dbh->prepare("Where 'column' LIKE '{:needle}'"); $stmt->bindParam(':needle', $needle); $stmt->execute();
cloudworks

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.