#Curso de SQL: La cláusula WHERE, filtrando datos

Publicado el 12 abril 2018 por Instintobinario

En este segundo capítulo del curso de SQL, vamos a profundizar en el uso de la cláusula WHERE. Hay multitud de opciones que se pueden aplicar a la misma, por lo que la estudiaremos a fondo. En el anterior artículo de éste curso, vimos las consultas más básicas para seleccionar, modificar o eliminar registros. Repasando, veíamos las siguientes sentencias:

SELECT * FROM Cliente WHERE Nombre = 'Lucia';
UPDATE Cliente SET Ciudad = 'Madrid' WHERE Nombre = 'Juan' AND Apellidos = 'Pérez Mora';
DELETE FROM Cliente WHERE Dni='11111111A';

Si no comprendes bien éstas instrucciones, repasa el artículo anterior antes de continuar la lectura.

Antes de comenzar, quiero dejar claro que todos los ejemplos que utilizaré en este capítulo son con la cláusula SELECT. Sin embargo, las mismas condiciones que utilicemos en el WHERE pueden aplicarse a UPDATE o DELETE.

Comparación de valores

Comenzamos viendo la diferencia en la comparación entre los diferentes tipos de datos. Para comparar números, simplemente podemos escribir dicho número.

SELECT * FROM Cliente WHERE Id = 1;

Sin embargo, para la comparación con cadenas de texto, utilizamos comillas simples (‘):

SELECT * FROM Cliente WHERE Nombre = 'Juan';

Pero puede que no siempre queramos comparar si un valor es igual a otro. Por eso, Oracle nos proporciona varios operadores de comparación que pasamos a describir a continuación:

  • Igual a (=): compara si dos valores son iguales uno al otro.
  • No igual (!=) (<>): comprara que los valores sean diferentes. En el caso de Oracle, este operador admite las dos formas, pero en otros sistemas de base de datos puede funcionar solo una.
  • Mayor que (>): Compara que el valor de la izquierda sea mayor que el de la derecha. En caso de comparar textos devolverá los que están después ordenados alfabéticamente.
  • Menor que (<): Compara que el valor de la izquierda sea menor que el de la derecha. En caso de comparar textos devolverá los que están antes ordenados alfabéticamente.
  • Mayor o igual que (>=): Compara que el valor de la izquierda sea igual o mayor que el de la derecha. La lógica con los textos es idéntica al anterior.
  • Menor o igual que (<=): Compara que el valor de la izquierda sea igual o menor que el de la derecha.
  • Entre (BETWEEN): Comprueba que los valores estén dentro de un rango, incluyendo los valores límite. Para los números funciona por valor, así BETWEEN 3 AND 5, devuelve los valores entre 3 y 5, ambos incluidos. Para los textos funciona en base al orden alfabético de los valores.
  • Comparador de patrón (LIKE): Hace una comparación en base a un patrón. Lo explicaré después.
  • Comparador de conjunto (IN): Permite especificar múltiples posibles valores para una columna.

Operadores lógicos: AND, OR y NOT

Cuando vamos a utilizar varias condiciones para una consulta, podemos especificarlas una tras otra. Sin embargo, esto nos da el problema de no saber si queremos que se cumpla ambas, o solo una de las mismas. Para indicar esto, tenemos los operadores ‘AND’ y ‘OR’.

El operador ‘AND’ indica que se debe cumplir la primera condición y se debe cumplir la segunda.

Así, en la siguiente sentencia nos devuelve los clientes llamados ‘Juan’ que sean de ‘Bilbao’.

SELECT * FROM Cliente WHERE Nombre='Juan' AND Ciudad = 'Bilbao';

Sin embargo, la siguiente sentencia no devolverá ningún valor pues es imposible que un cliente tenga dos nombres:

SELECT * FROM Cliente WHERE Nombre='Juan' AND Nombre = 'Lucia';

Si lo que queremos es obtener los clientes llamados ‘Juan’ junto a los clientes llamados ‘Lucia’. Utilizamos el operador ‘OR’. De esta forma indicaremos que se debe cumplir la primera condición o la segunda, o las dos.

SELECT * FROM Cliente WHERE Nombre='Juan' OR Nombre = 'Lucia';

En nuestro lenguaje natural solemos decir: “clientes llamados Juan y Lucia”. Sin embargo, esto es incorrecto desde el punto de vista lógico, pues nadie puede llamarse Juan y Lucia al tiempo. O te llamas Juan, o te llamas Lucia. Es importante aprender a pensar de ésta forma cuando programamos, ya que ésta lógica la comparten todos los lenguajes de programación.

Sé que esta explicación puede parecer absurda para los que ya sepan programar algo, pero en éste curso explico SQL desde el punto de vista de alguien que no sabe programar nada.

El último operador lógico que nos proporciona SQL es el NOT. Este operador niega la condición que se encuentre a continuación. Es decir, se seleccionarán los registros que no cumplan la condición especificada. Aquí se aplica la lógica de la doble negación igual a afirmación. Por ejemplo:

SELECT * FROM Cliente WHERE NOT Nombre != 'Juan';

Esta consulta seleccionará los Clientes cuyo nombre no cumpla la condición de no ser igual a Juan. Es decir, seleccionará los clientes llamados Juan. Funciona para cualquier operador lógico o de comparación.

Prioridad de los operadores

Los operadores de SLQ se pueden combinar de cualquiera de las formas, pero no se aplican por orden de lectura. Al igual que las operaciones matemáticas tienen un orden de prioridad, aquí pasa lo mismo. El orden para los operadores de SQL es: Operadores de comparación, NOT, AND y OR.

Veamos un ejemplo:

SELECT * FROM Cliente WHERE Ciudad = 'Madrid' OR Nombre = 'Patricia' AND Ciudad = 'Valladolid';

En esta sentencia, lo primero que se evalúa es Nombre = ‘Patricia’ AND Ciudad = ‘Valladolid’ Dando como resultado todos los clientes llamados Patricia que sean de Valladolid. A continuación, se evalúa la siguiente parte, Ciudad = ‘Madrid’, o los clientes que hayan sido seleccionados en las otras condiciones. Como resultado tenemos los clientes de Valladolid llamados Patricia junto a los clientes de Madrid.

Podemos cambiar ésta sentencia añadiendo paréntesis, los cuales modifican la prioridad de ejecución. Veamos cómo:

SELECT * FROM Cliente WHERE (Ciudad = 'Madrid' OR Nombre = 'Patricia') AND Ciudad = 'Valladolid';

En este caso se evalúa primero la parte (Ciudad = ‘Madrid’ OR Nombre = ‘Patricia’), por estar entre paréntesis. De ésta forma obtenemos los clientes de Madrid y los clientes que se llamen Patricia juntos. Después se evalúa los clientes que ya están este conjunto y que además sean de Valladolid. Como un cliente tiene una sola ciudad, tendremos los clientes Patricia de Valladolid, un resultado muy diferente como puede comprobarse.

Te animo a que practiques diseñando sentencias y tratando de averiguar el resultado para, a continuación, comprobar que has acertado.

Valores nulos y patrones

En  ocasiones, algunos campos de la base de datos no son rellenados al ser introducidos. Estos campos, decimos que son nulos. Es habitual querer preguntar por estos registros, tanto para obviarlos, como para obtener únicamente los mismos. Para este fin tenemos el valor NULL. Se trata de una palabra reservada que representa el valor de un campo vacío

Su uso es el siguiente:

SELECT * FROM Cliente WHERE Ciudad IS NULL;
SELECT * FROM Cliente WHERE Ciudad IS NOT NULL;

En la primera sentencia seleccionamos todos los clientes que no se les ha asignado ciudad (es NULL). En la segunda, seleccionamos todos los clientes que sí se les ha asignado ciudad (no es NULL).

¿Pero qué pasa si queremos consultar un campo con un valor no exacto? Es decir, todos los clientes que empiecen por ‘J’, o todos los clientes de ciudades cuya segunda letra sea la ‘a’. Para eso tenemos los patrones junto al operador LIKE.

Existen dos caracteres comodines en SQL:

  • % : representa una cadena de caracteres de cualquier extensión (incluso una cadena vacía).
  • _ : Representa un único carácter.

Veamos dos ejemplos de uso de un patrón con el operador LIKE para entenderlo:

SELECT * FROM Cliente WHERE Nombre LIKE 'J%';
SELECT * FROM Cliente WHERE Ciudad LIKE '_a%';

En la primera tenemos una selección de todos los clientes cuyo nombre comienza por J. En  la segunda tenemos una selección de todos los clientes de una ciudad cuya segunda letra sea la ‘a’.

Intervalos y listas

Por último, voy a explicar dos operadores que no he explicado suficientemente aún.

El primero es IN. Imagina que quieres seleccionar los clientes de Madrid, Zamora y Santander. Puedes hacer lo siguiente:

SELECT * FROM Cliente WHERE Ciudad = 'Madrid' OR Ciudad = 'Zamora' OR Ciudad = 'Santander';

Sin embargo, es engorroso tener que escribir 3 veces la palabra “Ciudad” concatenando las 3 condiciones con el operador OR. Si tuviésemos una lista de 15 ciudades, la consulta  sería demasiado larga y tediosa de escribir. Por eso el operador IN nos ayuda, pudiendo dar las ciudades en forma de lista:

SELECT * FROM Cliente WHERE Ciudad IN ('Madrid', 'Zamora', 'Santander');

Y por último, tenemos el operador BETWEEN. Este operador establece un intervalo de valores para seleccionar todos los valores que se encuentren en medio. Su uso es extremadamente simple, tal como vemos en el siguiente ejemplo:

SELECT * FROM Cliente WHERE Id BETWEEN 4 AND 6;

Esto es el equivalente a la siguiente consulta:

SELECT * FROM Cliente WHERE Id >= 4 AND Id <= 6;

Es importante que el valor límite inferior vaya en primer lugar, de lo contrario el conjunto de resultados será vacío.

También funciona con textos, considerando la ordenación alfabética de los mismos.

Probando los ejemplos de código de éste artículo

Para probar los ejemplos de código y experimentar con las consultas puedes ir al siguiente enlace:

http://sqlfiddle.com/#!4/348e3

En caso de estar en blanco el cuadro de texto sobre el botón “Build Schema”, pegar el siguiente código y pulsar sobre dicho botón.

CREATE TABLE Cliente (
Id int,
Dni varchar(9),
Nombre varchar(255),
Apellidos varchar(255),
Telefono varchar (255),
Ciudad varchar (255)
);

INSERT INTO Cliente(Id, Dni, Nombre, Apellidos, Telefono, Ciudad)
VALUES (1,'11111111A', 'Juan', 'Pérez Mora', '111111111', '');

INSERT INTO Cliente(Id, Dni, Nombre, Apellidos, Telefono, Ciudad)
VALUES (2,'22222222B', 'Isabel', 'Jimeno Hoyo', '22222222', 'Madrid');

INSERT INTO Cliente(Id, Dni, Nombre, Apellidos, Telefono, Ciudad)
VALUES (3,'33333333C', 'Patricia', 'Rodriguez Denia', '333333333', 'Valladolid');

INSERT INTO Cliente(Id, Dni, Nombre, Apellidos, Telefono, Ciudad)
VALUES (4,'44444444D', 'Mario', 'Fernandez Bosque', '444444444', 'Zamora');
INSERT INTO Cliente(Id, Dni, Nombre, Apellidos, Telefono, Ciudad)
VALUES (5,'55555555E', 'Lucia', 'Cobo Valero', '555555555', 'Santander');

INSERT INTO Cliente(Id, Dni, Nombre, Apellidos, Telefono, Ciudad)
VALUES (6,'66666666F', 'Clarise', 'Dupon', '666666666', 'Sevilla');

INSERT INTO Cliente(Id, Dni, Nombre, Apellidos, Telefono, Ciudad)
VALUES (7,'77777777G', 'Guillermo', 'Tuy Higuera', '777777777', 'Zamora');

INSERT INTO Cliente(Id, Dni, Nombre, Apellidos, Telefono, Ciudad)
VALUES (8,'88888888H', 'Juan', 'Dima Niquel', '888888888', 'Bilbao');

INSERT INTO Cliente(Id, Dni, Nombre, Apellidos, Telefono, Ciudad)
VALUES (9,'99999999I', 'Julieta', 'Montesco Lomas', '', 'Valladolid');

En el recuadro de la derecha se escriben las consultas y se ejecutan pulsando sobre “Run SQL”. En la parte inferior se mostrarán los resultados de la ejecución de la consulta. Para ver la diferencia después de las sentencias UPDATE o DELETE, ejecuta la sentencia:

SELECT * FROM Cliente;

Artículos anteriores del curso de SQL:

Capítulo 1: Introducción al SQL y las bases de datos relacionales

Capítulo 2: La cláusula WHERE, filtrando datos

El artículo #Curso de SQL: La cláusula WHERE, filtrando datos apareció por primera vez en Instinto Binario.