SQL · Guías · 30 de octubre de 2026 · 12 min de lectura

LIKE en SQL: comodines % y _, ILIKE, NOT LIKE, tildes y caracteres de escape

Un panel de salidas donde una lupa resalta todos los nombres de ciudad que empiezan por las mismas letras

LIKE filtra texto por un patrón en lugar de por un valor exacto. Un patrón tiene dos comodines: % equivale a cualquier secuencia de caracteres, también a ninguna, y _ equivale a exactamente un carácter. Así, city LIKE 'Mos%' encuentra todas las ciudades que empiezan por “Mos”, model LIKE '%300' los modelos que terminan en “300” y airport_name LIKE '%ovo%' los nombres que contienen “ovo” en cualquier posición. En PostgreSQL y DuckDB LIKE distingue mayúsculas y minúsculas; ILIKE es la versión que no las distingue. NOT LIKE invierte la condición, pero ninguno de los dos devuelve jamás filas en las que la columna sea NULL.

Todos los ejemplos usan la base de datos de una aerolínea del curso de SQL de Nomto, con sintaxis de PostgreSQL sobre DuckDB (el motor de la sala de SQL de Nomto). Los valores están en inglés y cada tabla de resultados es la salida real de la consulta.

Sintaxis de LIKE

SELECT columns
FROM table
WHERE text_column LIKE 'pattern';

El patrón es una cadena normal entre comillas simples. Sin comodines, LIKE se comporta como =; lo que lo hace útil son % y _. El patrón tiene que coincidir con el valor completo, y por eso importa tanto dónde pones el %:

patrón significa encuentra
'Mos%' empieza por “Mos” Moscow
'%sk' termina en “sk” Omsk, Tomsk, Irkutsk
'%ovo%' contiene “ovo” Domodedovo, Pulkovo
'_____' exactamente cinco caracteres Kazan, Sochi
'S_r%' S, un carácter cualquiera, r y luego lo que sea Saratov, Surgut

El comodín %: empieza por, termina en, contiene

Empieza por

SELECT airport_code, airport_name, city
FROM airports
WHERE city LIKE 'Mos%'
ORDER BY airport_code;
airport_code airport_name city
DME Domodedovo Moscow
SVO Sheremetyevo Moscow
VKO Vnukovo Moscow

Termina en

SELECT model
FROM aircrafts
WHERE model LIKE '%300'
ORDER BY model;
model
Boeing 737-300
Boeing 767-300
Boeing 777-300

Contiene

Un % a cada lado significa “en cualquier parte de la cadena”:

SELECT airport_name, city
FROM airports
WHERE airport_name LIKE '%ovo%'
ORDER BY airport_name
LIMIT 6;
airport_name city
Domodedovo Moscow
Ivanovo South Ivanovo
Kemerovo Kemerovo
Khomutovo Yuzhno-Sakhalinsk
Khrabrovo Kaliningrad
Koltsovo Yekaterinburg

El resultado completo tiene 12 aeropuertos; aquí la consulta se corta en seis filas.

“Contiene” suele atrapar más de lo que pretendes. Los nombres de pasajero se guardan como “NOMBRE APELLIDO” en mayúsculas. Si buscas el apellido Ivanov con '%IVANOV%' salen 14.040 billetes, pero con '% IVANOV' (un espacio y el apellido justo al final) solo 7.539:

SELECT CASE WHEN passenger_name LIKE '% IVANOV'  THEN 'IVANOV'
            WHEN passenger_name LIKE '% IVANOVA' THEN 'IVANOVA'
            ELSE 'other' END AS surname,
       COUNT(*) AS tickets
FROM tickets
WHERE passenger_name LIKE '%IVANOV%'
GROUP BY surname
ORDER BY tickets DESC;
surname tickets
IVANOV 7539
IVANOVA 6501

El patrón laxo se trajo sin avisar también la forma femenina, Ivanova. Es lo mismo que pasaría al buscar '%GARCIA%' en una base de clientes y encontrarte también “GARCIARENA”. Ancla el patrón todo lo que los datos permitan.

El comodín _: exactamente un carácter

_ representa un carácter, ni más ni menos. Cinco guiones bajos encuentran las ciudades de cinco letras:

SELECT city
FROM airports
WHERE city LIKE '_____'
ORDER BY city;
city
Anapa
Chita
Kazan
Kirov
Kursk
Kyzyl
Mirny
Nadym
Penza
Pskov
Sochi
Tomsk
Ukhta

Combinando los dos comodines: 'S_r%' significa S, un carácter cualquiera, r y después lo que sea.

SELECT city FROM airports WHERE city LIKE 'S_r%' ORDER BY city;
city
Saransk
Saratov
Strezhevoy
Surgut

Strezhevoy no es un error: S, luego la “t” ocupa el guion bajo y después la “r”. _ acepta cualquier carácter, consonantes incluidas.

Buscar sin distinguir mayúsculas: ILIKE y LOWER

En PostgreSQL y DuckDB, LIKE compara los caracteres tal cual, así que una minúscula no coincide con una mayúscula:

SELECT 'ABC' LIKE 'abc' AS like_result, 'ABC' ILIKE 'abc' AS ilike_result;
like_result ilike_result
false true

WHERE city LIKE 'mos%' no devuelve nada; WHERE city ILIKE 'mos%' devuelve los tres aeropuertos de Moscú. ILIKE no es SQL estándar: existe en PostgreSQL, DuckDB y Snowflake, pero no en MySQL ni en SQL Server. La forma portable es pasar los dos lados a minúsculas:

SELECT city FROM airports WHERE lower(city) LIKE 'mos%';

En MySQL y SQL Server, que distinga o no mayúsculas depende de la intercalación (collation) de la columna, y las de por defecto no las distinguen, así que allí un simple LIKE 'mos%' ya encuentra Moscow. Esa diferencia sorprende a menudo cuando una consulta pasa de una base de datos a otra.

Tildes y ñ: buscar “Bogotá” escribiendo “bogota”

En español el problema no son solo las mayúsculas. ILIKE ignora la caja, pero no las tildes:

SELECT 'Bogotá' ILIKE 'bogota%' AS ilike_result,
       strip_accents('Bogotá') ILIKE 'bogota%' AS sin_tildes;
ilike_result sin_tildes
false true

Cada motor lo resuelve a su manera:

NOT LIKE y por qué desaparecen las filas con NULL

NOT LIKE se queda con las filas que no coinciden. La trampa: si la columna es NULL, tanto LIKE como NOT LIKE devuelven NULL, y WHERE descarta la fila en los dos casos. Más o menos la mitad de los billetes tienen un email en contact_data; vamos a separarlos según la dirección contenga o no un guion bajo (cómo funciona \_ lo explica la siguiente sección):

SELECT COUNT(*) FILTER (WHERE contact_data->>'email' LIKE '%\_%' ESCAPE '\')     AS with_underscore,
       COUNT(*) FILTER (WHERE contact_data->>'email' NOT LIKE '%\_%' ESCAPE '\') AS without_underscore,
       COUNT(*) FILTER (WHERE contact_data->>'email' IS NULL)                    AS no_email,
       COUNT(*) AS total
FROM tickets;
with_underscore without_underscore no_email total
87828 111255 167650 366733

LIKE más NOT LIKE suman 199.083, no 366.733: los 167.650 billetes sin email no están en ningún grupo. Si “no coincide” debe incluir “no tiene valor”, dilo de forma explícita: WHERE email NOT LIKE '%\_%' ESCAPE '\' OR email IS NULL, o WHERE COALESCE(email, '') NOT LIKE .... La guía de NULL en SQL explica la lógica de tres valores que hay detrás.

Escapar: cómo buscar un % o un _ literal

Como % y _ son comodines, para buscar esos caracteres tal cual necesitas un carácter de escape. Sin él, “emails que contienen un guion bajo” coincide con todos los emails:

SELECT COUNT(*) AS emails,
       COUNT(*) FILTER (WHERE email LIKE '%_%')               AS unescaped,
       COUNT(*) FILTER (WHERE email LIKE '%\_%' ESCAPE '\')   AS escaped
FROM (SELECT contact_data->>'email' AS email FROM tickets) t
WHERE email IS NOT NULL;
emails unescaped escaped
199083 199083 87828

'%_%' significa “al menos un carácter, el que sea”, y eso lo cumple cualquier cadena no vacía. Con ESCAPE '\', la secuencia \_ significa un guion bajo de verdad.

El carácter de escape por defecto cambia de una base de datos a otra, y aquí es donde se rompen las consultas copiadas:

Una cláusula ESCAPE explícita funciona en todas, y puedes elegir el carácter que quieras, por ejemplo LIKE '%!_%' ESCAPE '!'.

Varios patrones a la vez

LIKE admite un solo patrón. Para varios, combina condiciones con OR y ponlas entre paréntesis si en el WHERE hay más condiciones:

SELECT city
FROM airports
WHERE (city LIKE 'Nov%' OR city LIKE 'Nor%')
ORDER BY city;
city
Norilsk
Novokuznetsk
Novosibirsk
Novy Urengoy

Sin paréntesis, WHERE a AND b OR c se lee como (a AND b) OR c, una fuente clásica de filas de más.

PostgreSQL acepta también city LIKE ANY (ARRAY['Nov%', 'Nor%']). DuckDB no: falla con Unsupported comparison "~~" for ANY/ALL subquery, así que en la sala de SQL de Nomto usa OR.

Cuando los patrones se complican, pasa a expresiones regulares. En DuckDB, regexp_matches(city, '^(Nov|Nor|Noy)') devuelve Norilsk, Novokuznetsk, Novosibirsk, Novy Urengoy y Noyabrsk. PostgreSQL usa el operador city ~ '^(Nov|Nor|Noy)'. Cuidado con ~ en DuckDB: allí la expresión tiene que coincidir con la cadena entera, así que city ~ '^Nov' no devuelve nada y necesitarías city ~ 'Nov.*'.

LIKE frente a =

= LIKE
Compara con el valor exacto un patrón con % y _
Comodines ninguno (% es un carácter normal) %, _
Velocidad siempre puede usar un índice solo usa índice con un prefijo fijo
Uso típico status = 'Arrived' city LIKE 'Nov%'

Usa = siempre que conozcas el valor completo. LIKE sin comodines da el mismo resultado que = en PostgreSQL y DuckDB ('abc ' LIKE 'abc' y 'abc ' = 'abc' son falsos los dos). En SQL Server, = ignora los espacios finales pero LIKE los tiene en cuenta, así que allí 'abc ' = 'abc' es verdadero y 'abc' LIKE 'abc ' es falso.

LIKE también funciona con fechas convertidas a texto, CAST(scheduled_departure AS VARCHAR) LIKE '2026-08-01%', y aquí da los mismos 568 vuelos que un rango. Aun así, quédate con el rango, scheduled_departure >= '2026-08-01' AND scheduled_departure < '2026-08-02': conserva el tipo de la columna, funciona en cualquier base de datos sea cual sea el formato de fecha como texto (en España y Latinoamérica es habitual ver 01/08/2026 al exportar) y puede usar un índice. Más detalles en la guía de funciones de fecha en SQL.

Rendimiento de LIKE

En una tabla grande, cómo empieza el patrón decide lo rápido que va:

Los motores analíticos columnares como DuckDB, BigQuery o Snowflake recorren columnas muy deprisa de todos modos, así que con un conjunto de datos del tamaño del curso no notarás la diferencia. En una tabla de producción de PostgreSQL, MySQL o SQL Server con millones de filas, sí.

Errores frecuentes

Para extraer partes de una cadena una vez encontrada (SPLIT_PART, SUBSTRING, REPLACE), mira la guía de funciones de texto en SQL. Los filtros con patrones también están en la chuleta de SQL.

Preguntas frecuentes

¿Qué significa % en LIKE?

% equivale a cualquier secuencia de caracteres, también a una vacía. 'Mos%' coincide con “Mos”, “Moscow” y cualquier otra cosa que empiece por “Mos”. _ equivale a exactamente un carácter.

¿LIKE distingue mayúsculas y minúsculas?

En PostgreSQL, DuckDB y Oracle, sí. En MySQL y SQL Server depende de la intercalación, y las de por defecto no las distinguen. Para no distinguirlas en PostgreSQL o DuckDB usa ILIKE, o lower(col) LIKE 'patrón' en cualquier base de datos.

¿Cómo busco sin tener en cuenta las tildes?

En DuckDB, strip_accents(col); en PostgreSQL, la extensión unaccent; en SQL Server, una intercalación _CI_AI como Modern_Spanish_CI_AI. En MySQL 8 la intercalación por defecto ya ignora tildes, aunque también confunde n con ñ.

¿Cómo escapo un guion bajo o un signo de porcentaje en LIKE?

Pon un carácter de escape delante y decláralo con ESCAPE: col LIKE '%\_%' ESCAPE '\' encuentra valores con un guion bajo real. PostgreSQL y MySQL usan la barra invertida por defecto; DuckDB y SQL Server no, así que la cláusula ESCAPE explícita es la forma portable. SQL Server acepta además '%[_]%'.

¿Puedo usar LIKE con varios valores?

No directamente. Combina condiciones con OR (city LIKE 'Nov%' OR city LIKE 'Nor%'), usa LIKE ANY (ARRAY[...]) en PostgreSQL o pasa a una expresión regular.

¿LIKE es más lento que =?

Un LIKE con prefijo fijo puede usar un índice y es casi tan rápido como =. Un patrón que empieza por % tiene que revisar todas las filas, lo que en tablas grandes es mucho más lento salvo que añadas un índice de trigramas (PostgreSQL) o de texto completo.

¿LIKE funciona con números?

En PostgreSQL primero hay que convertir: CAST(col AS TEXT) LIKE '12%'. MySQL convierte solo. Para números, una condición de rango (col BETWEEN 1200 AND 1299) casi siempre es mejor opción.

También en English, Português (Brasil), Tiếng Việt, 简体中文