MySQL sorgu dizesi içerir


307

Ben nasıl $haystackbelirli bir sütundaki değer (dize $needle), bu gibi belirli veri (dize ) içerip içermediğini denetler MySQL ile bir sorgu yapabilir anlamaya çalışıyorum :

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

PHP'de, işlev çağrılır substr($haystack, $needle), belki:

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

Yanıtlar:


437

Aslında oldukça basit:

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

%Belirlenen tüm karakterler (hiçbiri, bir veya birçok) için joker karakterdir. Bunun çok büyük veri kümelerinde yavaşlayabileceğini unutmayın, böylece veritabanınız büyürse tam metin dizinleri kullanmanız gerekir.


1
Bu yalnızca hazırlanmış bir sorgu kullanıyorsanız çalışır. Orada gerçek bir dize kullanıyorsanız (ör. Liquibase sql yükseltme betiği), aşağıda belirtilen INSTR'yi düşünün). Bunun nedeni, dizenizde bir% varsa, bununla bir şeyler eşleştirmeye başlamanızdır.
Ryan Shillington

2
i gibi sorguları hakkında bilmek, ama bugün ben bazı sütun dizede belirli bir değer olup olmadığını öğrenmek istedim ben bunun için googling .. Neden daha önce hiç düşünmedim ??
Cızırtılı Kod

1
bu durum hassas mı?
kızgın kivi

2
@angry_kiwi: column LIKE '...'büyük / küçük harfe duyarsız, column LIKE BINARY '...'büyük / küçük harfe duyarlı
Wolph

2
Bunu şaşırdım LIKEbu operatör iki joker karakterleri kullanır çünkü herhangi bir alt denetlemek için önerilmektedir: %ve _. Bu, $ iğne dizeniz bu özel karakterlerden birini içeriyorsa, sonuçların beklendiği gibi olmadığı anlamına gelir. (-1) bu yanıt için ve (+1) INSTR yanıtı için.
Skrol29

144

kullanın:

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

Referans:


GİBİ INSTR'den daha hızlı mı?
chris

17
@oedo: Bağlıdır. LIKE %...%mevcutsa bir indeks kullanmayacaktır, bu yüzden eşdeğer olmalıdırlar; LIKE ...%varsa bir dizin kullanır. Performans gerçek bir endişe ise, Tam Metin Arama (FTS) daha iyi bir yaklaşım olacaktır.
OMG Ponies

mükemmel. tam da aradığım şey.
arik

2
Aslında bu çözümü seviyorum, çünkü bir alt dizenin likeoperatörün varlığına göre işleri sıralamanın bir yolu yoktur . Böyle instrbir cümle ile sipariş edilebilirselect * from table order by instr(col1,"mystring")
Radacina

Bir alanda _'yi aramak istedim ve işe yaradı. Teşekkürler
Safeer Ahmed

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

2
_ (alt çizgi) karakterini ararken LIKE '% _%' sorgusu çalışmaz, bazı nedenlerden dolayı _ olmadan tüm dizeleri döndürür
Wojtek

1
@Wojtek _, herhangi bir tek karakter için bir joker karakterdir, bu nedenle gerçek bir alt çizgi aramak istiyorsanız, karakterden kaçmanız gerekir. Alt çizgi ile MySQL LIKE sorgusuna bakın .
jkmartindale

29

Benimki LOCATEMySQL'de kullanıyor :

LOCATE (substr, str), LOCATE (substr, str, konum)

Bu işlev çok baytlı güvenlidir ve yalnızca en az bir bağımsız değişken ikili dize olduğunda büyük / küçük harfe duyarlıdır.

Senin durumunda:

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

11
'sütun' sütun (tırnak işaretleri olmadan) olmalıdır
Wojtek

10

@WoLpH tarafından verilen yanıta ek olarak.

LIKEAnahtar kelimeyi kullanırken dizenin hangi yöne uyduğunu sınırlama imkanına da sahipsiniz. Örneğin:

Şununla başlayan bir dize arıyorsanız $needle:

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

Şununla biten bir dize arıyorsanız $needle:

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

3

bunun tehlikeli olduğunu unutmayın:

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

önce yap:

$needle = mysql_real_escape_string($needle);

böylece olası saldırıları önleyecektir.


7
* Bazı olası saldırılar. Ayrıca, mysql_real_escape_stringgelecekteki PHP sürümlerinde kullanımdan kaldırılacaktır.
Jack Tuck

11
Hazırlanan ifadeleri kullanmalı ve PHP'den kaçmayı bırakmalısınız. $stmt = $dbh->prepare("Where 'column' LIKE '{:needle}'"); $stmt->bindParam(':needle', $needle); $stmt->execute();
cloudworks

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.