Es una propiedad fundamental de NULL
que cuando se compara con nada — incluyendo NULL
— vuelve false
, que es la razón por lo que estás haciendo no funciona.
Así que la primera pregunta que debe responder es: ¿por qué quiere que se devuelva una fila con NULL
lastname
al ingresar a lastname
de "smith"? Posiblemente quiera decir que el primer nombre o el apellido debe coincidir para ser devuelto, en cuyo caso no está ejecutando la consulta correcta. La solución más ingenua es:
SELECT firstname, lastname, ....
FROM profiles
WHERE IFNULL(firstName LIKE'%{firstname}%'
OR lastName LIKE '%{lastName}%'
Ahora esto va a funcionar durante varios cientos y posiblemente miles de filas, pero no va a escalar más allá de eso por varias razones:
OR
s son típicamente muy débil en términos de actuación. Evítalos cuando sea posible. Si nos fijamos en las aplicaciones de bases de datos escritas por programadores experimentados, probablemente no encontrará una sola condición OR
(excepto de aquellos que hacen proselitismo las virtudes de OR
en la parte posterior de haber escrito una aplicación de libro de visitas que tiene 3 usuarios y 2 visitas al mes) ;
- Hacer un
LIKE
con un %
en el frente significará que no se demandarán los índices.
Existen varias soluciones para (2). Probablemente el más fácil en MySQL es usar full text searching en tablas MyISAM. No encontrará coincidencias como "Johannes" si escribe "han", pero en general es suficiente.
A menudo se trata de OR
condiciones usando UNION
o (preferiblemente) UNION ALL
en múltiples consultas. Por ejemplo:
SELECT firstname, lastname, ....
FROM profiles
WHERE firstName LIKE'%{firstname}%'
AND lastName LIKE '%{lastName}%'
UNION ALL
SELECT firstname, lastname, ....
FROM profiles
WHERE firstName LIKE'%{firstname}%'
AND lastname IS NULL
UNION ALL
SELECT firstname, lastname, ....
FROM profiles
WHERE firstName IS NULL
AND lastName LIKE '%{lastName}%'
UNION ALL
SELECT firstname, lastname, ....
FROM profiles
WHERE firstName IS NULL
AND lastName IS NULL
se ve grande y feo, pero UNION ALL
escalas extremadamente bien (ignorando el %
en el inicio de los criterios LIKE
). Básicamente está concatenando (en este caso) cuatro consultas. A UNION
hará un implícito DISTINCT
en las filas de resultados, pero sabemos que no habrá superposición aquí porque estamos variando la comprobación de NULL
.
Otra posibilidad es no tratar NULL
como algo que desea buscar. Esta es una solución mucho mejor e intuitiva (imho). Si alguien teclea el apellido de "Smith", ¿realmente quieres que aparezcan las filas con el apellido NULL
?
¿O desea que aparezcan porque es posible que haya encontrado una coincidencia con el primer nombre? Si es así, quieres una consulta ligeramente diferente. Por ejemplo:
SELECT firstname, lastname, ....
FROM profiles
WHERE id IN (
SELECT id
FROM profiles
WHERE firstName LIKE'%{firstname}%'
UNION ALL
SELECT id
FROM profiles
WHERE lastName LIKE '%{lastName}%'
)
¿Ha considerado usar LINQ-to-SQL? –
no, aún no he considerado linq a sql ... –