← Все курсы · Курс SQL

LIKE в SQL: сопоставление с образцом для начинающих

Инструмент для поиска внутри текстового столбца, а не просто сопоставления с ним. · Часть Analyst Prep Kit

К , аналитик данных · Обновлено

Большую часть времени вы запрашиваете у SQL точное значение. WHERE status = 'Active' Закрытый вопрос с ответом да или нет. Но многие реальные столбцы не содержат одного и того же значения. Они содержат предложение, название продукта с кодом, прикрепленным спереди, адрес электронной почты или список тегов, помещенных в одну ячейку. Для тех вам нужен более свободный вопрос, и LIKE это то, как вы это спрашиваете. Это небольшой фрагмент синтаксиса, состоящий ровно из двух движущихся частей, и как только они щелкнут, вы сможете искать внутри текста, а не просто сопоставлять его.

Версия из одного предложения. = спрашивает: «Это именно то значение?» LIKE спрашивает: «Соответствует ли это значение этой форме?» Форма записывается с двумя подстановочными знаками: % означает любой набор символов, включая отсутствие, и _ обозначает ровно один символ.
Что здесь
  1. Почему «равно» задает более строгий вопрос, чем вы хотите
  2. Два подстановочных знака, % и _
  3. Куда поставить %, вот и весь вопрос
  4. НЕ НРАВИТСЯ и нахожу то, чего не хватает
  5. Чувствительность к регистру, которая меняется в зависимости от базы данных.
  6. Ловушка чрезмерного соответствия
  7. Поиск столбца, содержащего список
  8. Соответствие буквальному % или _
  9. Почему LIKE '%Текст%' работает медленно
  10. Шпаргалка НРАВИТСЯ

Почему «равно» задает более строгий вопрос, чем вы хотите

Возьмите products стол с name столбец:

idимя
1Синяя хлопковая рубашка
2Зажимы для рубашек
3Красный шерстяной свитер
4Рубашка

Тебе нужны рубашки. Очевидная вещь терпит неудачу:

SELECT name
FROM products
WHERE name = 'Shirt';

Это возвращает одну строку с идентификатором 4, потому что = сравнивает все значение от начала до конца. Blue Cotton Shirt это не та же строка, что и Shirt, так что исключено, и это правильно. Равно делает свою работу. Это просто неправильный вопрос.

На самом деле у вас возникает вопрос: «Содержит ли имя где-нибудь слово «Рубашка»?» Это закономерность, а закономерности – это то, что LIKE предназначен для:

SELECT name
FROM products
WHERE name LIKE '%Shirt%';

Возвращаются три строки: Blue Cotton Shirt, Shirt Stay Clips, и Shirt.

Два подстановочных знака, % и _

Все LIKE могу сделать состоит из двух символов.

Подстановочный знакОзначаетПримерМатчи
%Любой набор символов, включая отсутствие вообще'S%'S, Sam, Sweater
_Ровно один символ, ни больше, ни меньше.'S_m'Sam, Sum, но не Steam

Часть «включая ничего вообще» % это то, чего людям не хватает. 'S%' соответствует одной букве S, потому что % разрешено стоять ни за что. Подчеркивание не так уж и снисходительно. Это требует присутствия персонажа.

Прежде чем прочитать ответ, произнесите это вслух: что бы '_at' соответствовать, и будет flat быть в списке? Сначала обязуйтесь ответить.

Он соответствует трехсимвольным значениям, оканчивающимся на at, так cat, hat, bat. flat отсутствует, потому что _ охватывает один символ и flat имеет два перед at. Если бы вы хотели и то, и другое, вы бы написали '%at'.

Вы можете смешивать их. 'A__-%' соответствует значению, которое начинается с A, есть еще ровно два символа, потом дефис, потом что угодно. Это полезная форма для кодов продуктов и номеров счетов, где формат фиксирован, а содержимое — нет.

Куда поставить %, вот и весь вопрос

Один и тот же подстановочный знак, четыре позиции, четыре совершенно разных вопроса. Эту таблицу стоит запомнить:

Ты пишешьВы спрашиваетеСоответствует «Синей хлопковой рубашке»?
LIKE 'Shirt'Это именно Рубашка (то же, что и =)Нет
LIKE 'Blue%'Это начинается с синего?Да
LIKE '%Shirt'Это заканчивается рубашкой?Да
LIKE '%Cotton%'Содержит ли он где-нибудь хлопок?Да

A LIKE шаблон без подстановочных знаков просто медленнее =. Если ты напишешь LIKE 'Shirt' вы запросили точное совпадение и должны использовать = вместо этого это будет более понятно тому, кто прочитает запрос следующим.

Прочитайте схему слева направо, прописью. '%Cotton%' читается как «что угодно, потом Коттон, потом что угодно». 'Blue%' читается как «Синий, потом что угодно». Если вы сможете произнести образец в виде предложения, вы не поставите знаки процента не в том месте.

НЕ НРАВИТСЯ и нахожу то, чего не хватает

Помещать NOT впереди и вы получите противоположный набор:

SELECT name
FROM products
WHERE name NOT LIKE '%Shirt%';

Это возвращает строки без Shirt в них. Это более полезно, чем кажется на первый взгляд, потому что «какие строки нет соответствуют ожидаемой форме» — один из самых продуктивных вопросов при очистке данных. Электронные письма без знака «в», коды продуктов без префикса, текстовый столбец, в некоторых строках которого содержится список, а в некоторых — нет. NOT LIKE находит лишние.

Одна загвоздка, о которой стоит знать сейчас. Строка, в которой находится столбец NULL не возвращается ни LIKE ни NOT LIKE. NULL означает неизвестное, и SQL не будет утверждать, что неизвестное значение соответствует или не соответствует шаблону. Если вам тоже нужны заготовки, попросите их: WHERE name NOT LIKE '%Shirt%' OR name IS NULL. Полная история находится в NULL в SQL.

Чувствительность к регистру, которая меняется в зависимости от базы данных.

Ли '%shirt%' находит Blue Cotton Shirt зависит от того, в какой базе данных вы находитесь. Это удивляет людей, которые перемещаются между двумя из них, поэтому стоит один раз проверить, а не предполагать.

база данныхLIKE чувствителен к регистру?Как заставить нечувствительного
SQLiteНет для простых букв от A до Z, да для букв с акцентом и неанглийских букв.Уже нечувствителен к А-Я
PostgreSQLДа Использовать ILIKE
MySQLЗависит от параметров сортировки столбцов, обычно нетОбычно уже нечувствителен
SQL ServerЗависит от сортировки, обычно нетОбычно уже нечувствителен

Переносной ход, если вы хотите, чтобы везде был один и тот же ответ, — это сгладить обе стороны самостоятельно:

SELECT name
FROM products
WHERE LOWER(name) LIKE '%shirt%';

Это работает в каждой базе данных, перечисленной выше, ценой небольшого снижения скорости. См. последний раздел, чтобы узнать, почему.

Ловушка чрезмерного соответствия

Предскажите это, прежде чем читать дальше. Вы выполняете поиск по жанровому столбцу с помощью LIKE '%Video%'. Что возвращается?

В реальном наборе данных игр Пар этот шаблон соответствует обоим Video Production и 360 Video, потому что оба содержат эти пять букв. Это может быть именно то, что вы хотели, или это может незаметно удвоить ваш набор результатов.

% не знает границ слов. Оно соответствует буквам, а не смыслу. Немного классики:

ШаблонТы имел в видуВы также получаете
'%art%'искусствотелега, старт, Барт, частица
'%man%'мужчинауправлять, человек, Германия
'%IT%'ИТ-отделкредит, выход, монитор (где LIKE не чувствителен к регистру)

Решение состоит в том, чтобы придать рисунку больше устойчивости. Если значения разделены известным символом, включите его: '%, Sales%' гораздо точнее, чем '%Sales%'. В следующем разделе показана надежная версия этого трюка.

Поиск столбца, содержащего список

Вот к чему стремятся аналитики LIKE чаще всего. Некоторые столбцы упаковывают в одну ячейку несколько значений, разделенных запятыми:

имяжанры
Игра АЭкшен, Инди, Ролевая игра
Игра БКазуальная игра, Инди
Игра СRPG

= здесь бесполезен, потому что почти ни одна ячейка не содержит только RPG. LIKE обрабатывает его без какого-либо разделения:

SELECT name
FROM games
WHERE genres LIKE '%RPG%';

Он находит игру A и игру C, независимо от того, находится ли тег первым, последним или скрыт посередине.

Точная версия защищает от ловушки чрезмерного совпадения. Оберните значение в разделитель с обеих сторон, затем найдите разделенный тег:

SELECT name
FROM games
WHERE ',' || genres || ',' LIKE '%,RPG,%';

тот || склеивает текст вместе, поэтому Action,Indie,RPG временно становится ,Action,Indie,RPG,. Теперь каждый тег имеет запятую с обеих сторон, включая первую и последнюю, а также шаблон '%,RPG,%' может соответствовать только целому тегу. Жанр под названием RPGMaker больше не будет ложным попаданием. Использовать CONCAT(',', genres, ',') вместо || в MySQL и SQL Server.

Такая форма столбца вызывает больше проблем, чем просто поиск, включая отдельные подсчеты, которые возвращаются неправильно и никогда об этом не говорят. Одна ячейка, много значений охватывает всю проблему.

Соответствие буквальному % или _

Время от времени персонаж, за которым вы ищете, является подстановочным знаком. Поиск в столбце примечаний фактического знака процента с помощью LIKE '%%%' соответствует каждой строке, что бесполезно. Объявите побег-символ и отметьте буквальный:

SELECT note
FROM feedback
WHERE note LIKE '%!%%' ESCAPE '!';

Прочтите этот шаблон так: что угодно, затем настоящий знак процента (тот, что после !), тогда ничего. ESCAPE '!' в конце то, что сообщает SQL, что ! это маркер. Вы можете выбрать для задания любого персонажа, если он не указан в ваших данных. То же самое относится и к буквальному подчеркиванию, которое имеет большее значение, чем вы думаете, поскольку подчеркивания присутствуют повсюду в именах столбцов и кодах продуктов.

Почему LIKE '%Текст%' работает медленно

Указатель текстового столбца работает так же, как указатель в конце книги: записи сортируются в алфавитном порядке, поэтому база данных может сразу перейти в нужное место. Это работает, если вы знаете, как начинается значение.

ШаблонМожет ли индекс помочь?Почему
'Blue%'ДаВсе, что начинается с Синий, хранится вместе.
'%Shirt'НетНачало неизвестно, поэтому прыгать некуда.
'%Cotton%'НетТа же проблема, каждую строку нужно читать и проверять.

На нескольких тысячах строк это незаметно. На десятки миллионов это разница между мгновенным ответом и перерывом на кофе. Это не повод избегать '%text%', это повод узнать, почему запрос замедлялся при росте таблицы. Если вам нужен быстрый поиск внутри текста в масштабе, то это индекс полнотекстового поиска, другой инструмент. Индексирование для аналитиков охватывает то, что может и не может делать индекс.

Та же логика объясняет стоимость LOWER(name) LIKE ... из более раннего. Обертывание столбца в функцию означает, что индекс этого столбца больше не применяется, поскольку в индексе хранятся исходные значения, а не строчные значения.

Шпаргалка НРАВИТСЯ

Вы хотите… Писать
Содержит словоLIKE '%word%'
Начинается сLIKE 'word%'
Заканчивается наLIKE '%word'
Именно это= 'word', НЕ НРАВИТСЯ
Не содержитNOT LIKE '%word%'
Ровно один неизвестный персонажLIKE 'A_C'
Фиксированный формат, например три буквы, затем тире.LIKE '___-%'
Нечувствителен к регистру вездеLOWER(col) LIKE '%word%'
Нечувствителен к регистру в PostgreSQLILIKE '%word%'
Один целый тег из списка, разделенного запятыми.',' || col || ',' LIKE '%,tag,%'
Буквальный знак процентаLIKE '%!%%' ESCAPE '!'
Скажите это вслух, прежде чем запустить. Прочтите шаблон слева направо как предложение, заменяя каждое слово «что угодно». %. Если произнесенное вами предложение не является тем вопросом, который вы хотели задать, знаки процента стоят не на том месте. Эта одна привычка мешает большинству LIKE ошибки.
Подробнее об этом и еще что-нибудь подобное. Все инструкции находятся в одном месте на индекс направляющих: SQL, Tableau, миграция данных и связанные с ними рабочие привычки.
Вы написали LIKE '%искусство%' и получили обратно тележку, старт и Барт, и ни одна ошибка не произнесла ни слова.

SQL для аналитиков составляет 458 страниц рабочих ответов, при этом нечетные случаи прописаны, а не пропущены.

SQL для аналитиков, 19 $ →
Сделайте WHERE, GROUP BY, JOIN и все остальное привычным.

тот Курс SQL обучает основам аналитического SQL на рабочих примерах, интерактивной лаборатории JOIN и Агрегация, которую вы запускаете в браузере, флэш-карточках и пробном экзамене. Нечего устанавливать.

Откройте набор SQL →

Или приступайте к делу и учитесь, написав запросы: открыть SQL-практикум, тринадцать запросов, каждый из которых добавляет что-то одно к последнему.