Рядок запитів MySQL містить


307

Я намагався з'ясувати, як я можу зробити запит за допомогою MySQL, який перевіряє, чи значення (рядок $haystack) у певному стовпці містить певні дані (рядок $needle), наприклад:

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

У PHP функція викликається substr($haystack, $needle), тому, можливо:

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

Відповіді:


437

Насправді просто:

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

Це %підстановка для будь-якого набору символів (жодного, одного чи багатьох). Зверніть увагу, що на дуже великих наборах даних це може повільно, тому якщо ваша база даних зростає, вам потрібно буде використовувати повнотекстові індекси.


1
Це буде працювати лише в тому випадку, якщо ви використовуєте підготовлений запит. Якщо ви використовуєте фактичний рядок там (наприклад, скрипт оновлення sqd-версії для ліквідування), то розгляньте INSTR, зазначений нижче). Це тому, що якщо ваш рядок містить%, ви почнете відповідати речам із ним.
Райан Шиллінгтон

2
я знаю про подібні запити, але все ж сьогодні я хотів з’ясувати, чи існує певне значення в рядку в якомусь стовпці, я за ним гуглив .. Чому я ніколи раніше про це не думав ??
Код

1
чи чутливий цей випадок?
сердитий ківі

2
@angry_kiwi: column LIKE '...'це нечутливе до регістру, column LIKE BINARY '...'воно чутливе до регістру
Wolph

2
Я здивований, що LIKEпропонується перевірити будь-яку підрядку, оскільки цей оператор використовує два символи підстановки: %і _. Це означає, що якщо у вашій стрічці $ needle є один із цих спеціальних символів, результати взагалі не такі, як очікувалося. (-1) для цієї відповіді та (+1) для відповіді INSTR.
Skrol29

144

Використання:

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

Довідка:


напевно LIKE швидше, ніж INSTR?
chris

17
@oedo: Залежить. LIKE %...%не використовуватиме індекс, якщо такий присутній, тому він повинен бути еквівалентним; LIKE ...%використовував би індекс, якщо такий є. Якщо продуктивність викликає серйозне занепокоєння, кращим підходом був би пошук текстового тексту (FTS).
OMG Ponies

досконалий. саме те, що я шукав.
арік

2
Мені подобається це рішення, оскільки насправді немає можливості сортувати речі відповідно до наявності підрядки з likeоператором. Із instrтакою фразою можна замовити такselect * from table order by instr(col1,"mystring")
Radacina

Я хотів шукати _ у полі, і це спрацювало. Спасибі
Безпечний Ахмед

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

2
під час пошуку символу _ (підкреслити) запит LIKE '% _%' не працює, чомусь він повертає всі рядки навіть без _
Wojtek

1
@Wojtek _ - це підстановка для будь-якого окремого символу, тому якщо ви хочете шукати буквальний підкреслення, вам потрібно буде його уникнути. Дивіться запит MySQL LIKE з підкресленням .
jkmartindale

29

Шахта використовується LOCATEв mysql:

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

Ця функція безпечна у кількох байтах і відрізняється від регістру, лише якщо принаймні один аргумент є двійковим рядком.

У вашому випадку:

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

11
'колонка' повинна бути стовпчиком (без лапок)
Войтек

10

Окрім відповіді від @WoLpH.

При використанні LIKE ключове слово, ви також маєте можливість обмежувати, у якому напрямку відповідає рядок. Наприклад:

Якщо ви шукали рядок, що починається з вашого $needle:

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

Якщо ви шукали рядок, який закінчується на $needle:

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

3

пам'ятайте, що це небезпечно:

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

робити спочатку:

$needle = mysql_real_escape_string($needle);

тому це запобіжить можливі атаки.


7
* Деякі можливі атаки. Крім того, mysql_real_escape_stringце буде застарілим у майбутніх випусках PHP.
Джек Так

11
Вам слід скористатися підготовленими висловлюваннями та залишити проходить до PHP. $stmt = $dbh->prepare("Where 'column' LIKE '{:needle}'"); $stmt->bindParam(':needle', $needle); $stmt->execute();
хмарні роботи

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.