Tutorial de SQL. SELECT Parte I

Introducción

En la entrega anterior vimos una pequeña introducción al comando SELECT de SQL. En él vimos el uso más básico de este comando, es decir, su uso para realizar consultas sencillas de selección y obtener datos de una o varias tablas.

En un 90% de las situaciones ese será el tipo de consultas que utilicemos, sin embargo en ocasiones, ese 10% restante, necesitamos algo más preciso, un comando de selección que nos permita obtener justamente los datos que necesitamos y que no se refieren directamente a una tabla sino que son, quizá, suma de dos o más tablas, intersecciones, obtener los resultados agrupados, ordenados, etc... La sentencia SELECT nos permite hacer todo este tipo de cosas.

Sintaxis

Como ya vimos en la introducción anterior la sintaxis general de una consulta de selección SELECT es la siguiente:

SELECT Tabla1.campo1, Tabla2.campo2 FROM Tabla1, Tabla2 WHERE condiciones

aunque una descripción más detallada es

SELECT [DISTINCT] t1.campo2 [AS NombreCampo1], t2.campo2 [AS NombreCampo2] {,....}
[FROM Tabla1 [t1], Tabla2 [t2] {,...} WHERE condiciones]
[GROUP BY {campos}]
[HAVING condiciones]
[ORDER BY {campos}]

Nota: Las llaves en la sentencia indican la posibilidad de ampliar la sentencia con más campos o tablas. Los parametros entre corchetes no son obligatorios sino opcionales

Tabla1 y Tabla2 indican nombres de tablas de la base de datos. Para bases de datos basadas en esquemas (como por ejemplo Oracle) dicho nombre debe constituir el identificador completo, incluyendo el nombre del esquema, por ejemplo Gestion.Clientes.

La palabra clave DISTINCT

La palabra clave DISTINCT nos permite indicar que deseamos filtrar los resultados repetidos, esto es, no devolver nunca dos filas exactamente iguales. Esta comparación se realiza entre dos filas completas es decir, para la siguiente tabla (que no esta en forma normal pero sirve para el ejemplo)

Nombre Facturacion Mes
Manuel 2300 Enero
Zackarias 3500 Marzo
Sandra 1900 Marzo
Manuel 2900 Mayo
Sandra 1900 Junio

Si realizamos la consulta

SELECT DISTINCT Nombre FROM Clientes

obtendremos

Nombre
Manuel
Zackarias
Sandra

mientras que si realizamos

SELECT DISTINCT Nombre, Facturacion FROM Clientes

obtendremos

Nombre Facturacion
Manuel 2300
Zackarias 3500
Sandra 1900
Manuel 2900

en el que aparece Sandra una sola vez (puesto que conicide tanto el nombre como la facturación) mientras que Manuel aparece dos veces puesto que, aunque el nombre coincide, la facturación es distinta y por lo tanto se trata de dos filas diferentes.

La palabra clave AS

La palabra clave AS permite asignar un alias a cada nombre de campo, es decir, asignarle un nombre más "legible" a un determinado campo de la base de datos que, por una razón o por otra, tiene un nombre poco adecuado.

SELECT nombre_completo AS "Nombre Completo", Fecha AS "Fecha Primera Transacción" FROM Proveedores

Los nombres de tabla

Como podemos observar, de forma opcional podemos asignar un alias a cada tabla poniendo el nombre de dicho alias a continuación del nombre de la tabla. Todas la referencias a la tabla podrán entonces hacerse refiriendose al alias (t1.campo frente a Tabla1.campo). Lo mismo ocurre con los campos seleccionados a los que podremos asignar un nombre situandolo a continuación del nombre de dicho campo y precediendolo de la palabra reservada as como puede verse en la sentencia anterior.

El simbolo *

En ocasiones al obtener datos de una tabla es posible que no deseemos limitar los campos (las columnas) que recibimos sino que queramos obtener todos y cada uno de los campos que componen la tabla podemos utilizar el simbolo *. Veamos un ejemplo:

SELECT * FROM Clientes WHERE IdCliente = 1;

Obtendría todos los campos correspondientes al cliente cuyo id es el 1.

Nota: Puede observarse que cuando tan solo hay una tabla en la consulta se puede obviar el paso de prefijar el nombre de los campos con el nombre de la tabla. Esto es así en general cuando no existe posibilidad de ambigüedad en dichos nombres, es decir, se puede obviar para todos aquellos campos que no existan con el mismo nombre en distitnas tablas incluidas en la consulta.

Si queremos obtener todos los campos de una tabla pero solo algunos de una segunda:

SELECT Facturas.*, Clientes.Nombre FROM Clientes, Facturas

Que obrendría todos los campos de la tabla Facturas pero solo el nombre de la tabla Clientes.

La clausula WHERE

El primer lugar en el que comienza la complejidad de las clausulas de selección nos lo proporciona la clausula WHERE. En el paso anterior vimos algunos ejemplos básicos de su uso para obtener información de las tablas filtrando parte de la información. Vamos a adentrarnos un poco más ahora en su uso.

La clausula WHERE nos permite imponer condiciones o filtros en la selección indicada por la consulta. Expresado en un lenguaje coloquial nos permite decir: "de los datos que te he pedido, dame solo los que cumplan estas condiciones" y constituye la herramienta fundamental de casi toda sentencia SELECT.

Como ya vimos podemos escribir sentencias para obtener solo datos parciales de una tabla por ejemplo seleccionando todas las entradas de la tabla clientes cuyo nombre es "Pedro"

SELECT * FROM Clientes WHERE nombre='Pedro'

o bien utilizar la consulta para "mezclar" datos de varias tablas por ejemplo seleccionando todas las facturas pertenecientes a un cliente

SELECT Facturas.* FROM Facturas, Clientes
WHERE Clientes.Nombre = 'Pedro' AND
           Facturas.IdCliente = Clientes.IdCliente

La traducción literal de la sentencia anterior es: "dame todos los datos de la tabla facturas (facturas.*) cogiendo la tabla facturas y la tabla clientes en las que el nombre del cliente sea pedro y el id de la factura corresponda con el id del cliente". O dicho de otra forma, dame todas las facturas de todos los usuarios cuyo nombre sea pedro.

Para comprender mejor como funciona una clausula de selección WHERE podemos imaginarnos que la consulta se va ejecutando por pasos. Así en el caso anterior establecemos primero los resultados a aquellos clientes cuyo nombre es Pedro. Dichos clientes tendrán apellidos, dirección, etc y un identificador de cliente que es el que utilizamos en la segunda parte de la clausula diciendole, "ahora, de los anteriores, coge aquellas facturas cuyo id de cliente coincide.

Un 90% de las consultas SQL no necesitan nada más complicado que una clausula WHERE para limitar los parametros que buscamos en la base de datos.

Comandos de selección de la clausula WHERE

Comparaciones

Como ya hemos visto en algunos ejemplos, el comando de selección más común en una clausula WHERE son las comparaciones, y de hecho, dentro de ellas, la más común es la de igualdad, como veíamos en el ejemplo anterior:

SELECT * FROM Clientes WHERE nombre='Pedro'

Además de dicha comparación podemos utilizar cualquiera de los operadores de inigualdad como son mayor (>), menor (<), mayor o igual(>=), menor o igual (<=) y distinto (<>). Estos operadores pueden aplicarse tanto a campos de tipo número como a campos de tipo cadena. Para los primeros tienen el valor obvio de ordenación y para los segundos siguen el orden alfabético (en el caso <). Vamos a ver un par de ejemplos

SELECT * FROM Clientes WHERE nombre<>'Pedro'

Estaremos seleccionando todos aquellos clientes cuyo nombre no es Pedro.

SELECT * FROM Clientes WHERE nombre>'Pedro'

Estaremos seleccionando todos aquellos clientes cuyo nombre es posterior (alfabéticamente) a Pedro, un ejemplo de salida podría ser:

IdCliente Nombre Apellidos Facturacion Cliente_desde
13 Tony Ramstein 8000 1993
18 Zackarias Conner 3500 2004
26 Sara García 29000 1995
SELECT * FROM Clientes WHERE facturacion <= 5000
IdCliente Nombre Apellidos Facturacion Cliente_desde
10 Manuel Martínez 2300 1999
15 Zackarias Conner 3500 2004
16 Sandra González 1900 1992

Estaremos seleccionando todos aquellos clientes cuya facturación sea inferior o igual a 5000 €, un ejemplo de salida podría ser:

IN y BETWEEN

Los operadores IN y BETWEEN nos permiten especificar rangos de valores válidos para los resultados de nuestra consulta, ya sea especificando una cota superior e inferior o un conjunto de valores.

El operador IN nos permite especificar un conjunto de valores, separados por comas, que serán considerados "válidos" para el campo especificado. Veamos un ejemplo:

SELECT * FROM Clientes WHERE  Cliente_desde IN (1995, 1997, 1999)

Nos devolverá todos aquellos clientes que sean clientes nuestros desde 1995, 1997 o 1999

IdCliente Nombre Apellidos Facturacion Cliente_desde
10 Manuel Martínez 2300 1999
26 Sara García 29000 1995

SELECT * FROM Clientes WHERE  Nombre IN ('Pedro', 'Sara')

Nos devolverá todos aquellos clientes que se llamen Pedro o Sara.

IdCliente Nombre Apellidos Facturacion Cliente_desde
1 Pedro Martín 8500 2000
26 Sara García 29000 1995

Por su lado el operador BETWEEN, que significa "entre" en inglés, nos permite especificar un limite inferior y superior para el valor deseado, por ejemplo:

SELECT * FROM Clientes WHERE facturacion BETWEEN 1400 AND 5000

Nos devolvería todos los clientes cuya facturación está entre 1400 y 5000 €.

LIKE

El operador LIKE nos permite seleccionar todos aquellos valores que se aproximan a un patrón, es decir, nos permite realizar selecciones más avanzadas que se "parezcan" a un valor determinado. Podemos utilizar dos caracteres especiales con este operador:

  • El simbolo especial % indica cualquier cadena.
  • El simbolo especial _ indica cualquier caracter.

De esta forma la sentencia 'm_ma%' indica cualquier cadena que empiece por "m" seguida de cualquier caracter, seguida de la secuancia "ma" seguida de cualquier cadena, así por ejemplo serían cadenas válidas "mama", "mamarracho" o "mimanos". Por ejemplo:

SELECT * FROM Clientes WHERE nombre LIKE '_ed%'

Que por ejemplo devolvería las entradas de Pedro y Medina

SELECT * FROM Clientes WHERE nombre LIKE '___'

Que nos devuelve todos aquellos clientes cuyo nombre tiene exactamente 3 caracteres (hay tres '_') como por ejemplo Ana

La clausula ORDER BY

Muy bien, ya tenemos los resultados que queremos, pero en algunos casos tendremos la necesidad de ordenar dichos resultados según algún criterio, como puede ser el nombre del cliente, el precio de la factura o cualquier otro tipo de criterio que se nos ocurra.

Para obtener un cierto orden en los registros se utiliza la clausula la clausula ORDER BY que funciona sencillamente especificando los campos por los que queremos ordenar el resultado. Por ejemplo, ampliando la consulta anterior:

SELECT Facturas.* FROM Facturas, Clientes
WHERE Clientes.Nombre = 'Pedro' AND
           Facturas.IdCliente = Clientes.IdCliente
ORDER BY Facturas.Precio

o esta misma sentencia que es equivalente

SELECT Facturas.* FROM Facturas, Clientes
WHERE Clientes.Nombre = 'Pedro' AND
           Facturas.IdCliente = Clientes.IdCliente
ORDER BY Facturas.Precio ASC

Nos permite obtener las facturas de los clientes ordenadas por su precio, de menor a mayor. El orden por defecto de una ordenación es ascendiente, es decir, los valores "más pequeños" primero. Esto se aplica tanto numéricamente como alfabéticamente en función del tipo de campo sobre el que estemos tratando. En realidad existen dos especificaciones de orden, ASC y DESC. ASC es la función por defecto mientras que DESC ordena en sentido contrario, es decir, los "mayores" primero. De forma que si queremos rehacer la consulta anterior pero mostrando primero las facturas cuyo precio es mayor:

SELECT Facturas.* FROM Facturas, Clientes
WHERE Clientes.Nombre = 'Pedro' AND
           Facturas.IdCliente = Clientes.IdCliente
ORDER BY Facturas.Precio DESC

También podemos incluir más campos en el criterio de ordenación, en orden, es decir, primero se ordenará por el primero que pongamos y si hay dos o más valores iguales se ordenarán por el siguiente, etc. Por ejemplo:

SELECT Facturas.* FROM Facturas, Clientes
WHERE Clientes.Nombre = 'Pedro' AND
           Facturas.IdCliente = Clientes.IdCliente
ORDER BY Facturas.Precio, Facturas.NumeroItems

que nos mostrará primero las facturas cuyo precio sea menor y, si dos facturas tienen el mismo precio, primero aquellas cuyo número de items sea menor. Si quisieramos, por ejemplo, que se mostraran primero las facturas cuyo precio es mayor y, si hay dos con el mismo precio, aquellas cuyo numero de items es menor

SELECT Facturas.* FROM Facturas, Clientes
WHERE Clientes.Nombre = 'Pedro' AND
           Facturas.IdCliente = Clientes.IdCliente
ORDER BY Facturas.Precio DESC, Facturas.NumeroItems ASC

9.75
Average: 9.8 (4 votes)
Your rating: None