SELECT en SQL

En una entrada anterior vimos que SQL es lenguaje que se utiliza para interactuar con bases de datos relacionales. A su vez, el lenguaje se divide en cláusulas o comandos, que nos permiten realizar distintas operaciones.

Hoy vamos a ver una de las más importantes, la cláusula SELECT, que nos permite recuperar la información de la base de datos. Para ello, seguimos donde lo dejamos en la entrada anterior. Al seguir las instrucciones anteriores, tendrás una base de datos con una tabla que tiene 8837 filas de datos.

Al dar nuestros primeros pasos ya ejecutamos una consulta de éste tipo. La sintaxis general del SELECT es la siguiente:

--Para seleccionar todas las columnas
SELECT * FROM Tabla

Para escribir un comentario en SQL podemos utilizar -- al principio de una línea

Vemos que es bastante intuitivo, básicamente es como pedirle lo que queremos a la base de datos, pero en inglés. El único carácter que puede parecer extraño es *, que en programación (se usa en otros sitios además de en SQL) suele significar “todo”. Por tanto, ésta consulta selecciona todas las variables o columnas de la tabla. Podríamos traducirla al español como “Selecciona todo lo que hay en la tabla que se llama Clima y muéstramelo”

También podemos seleccionar columnas específicas separándolas por comas. Ésto es útil, ya que generalmente no necesitamos trabajar con todas las variables de las tablas a la vez sino únicamente con unas pocas (especialmente cuando estamos desarrollando aplicaciones). De ésta forma, si trabajamos por ejemplo desde R o python cargaremos menos información en memoria, y se acelera la lectura de los datos.

--Seleccionamos columnas especificas
SELECT Variable1, Variable2, Variable3 FROM Tabla

Por cierto, si te fijas, suelo escribir los comandos SQL en mayúsculas, y el resto de los elementos de forma normal. Ésto se hace así por convención, ya que nos permite distinguir mejor el código de nuestra nomenclatura para nombrar las cosas. No obstante es opcional, SQL no suele distinguir entre mayúsculas o minúsculas (con algunas excepciones).

A las expresiones SQL completas (es decir, que no dan error por que falte algún componente) se las denomina consultas, ya que le “pedimos” información a la base de datos

Cláusula WHERE

Otra situación muy frecuente es que queramos recuperar únicamente las filas o los casos de la base de datos que cumplan una serie de condiciones. Aquí es donde entra la cláusula WHERE. Su sintaxis general es la siguiente:

SELECT * FROM Tabla WHERE Condicion

Si ejecutamos la siguiente consulta en DB Browser for SQLite filtrará las observaciones de la tabla para devolver las filas de la estación de Segovia:

SELECT * FROM datos_aemet WHERE estacion == "SEGOVIA"

Nos devuelve 181 filas, y el campo estacion en todas ellas tiene el valor “SEGOVIA”. También podemos especificar varias condiciones, para lo que podemos utilizar los siguientes operadores:

SELECT * FROM datos_aemet WHERE estacion == "SEGOVIA" AND tmed > 20

Ésta consulta nos devuelve las filas que pertenecen a la estación de Segovia y en las que la temperatura media (tmed) ha sido superior a 20 grados. Podemos encadenar más condiciones si queremos. En éstos casos, podemos utilizar paréntesis para agrupar condiciones. Por ejemplo

Operadores lógicos

A su vez, las condiciones pueden utilizar operadores lógicos, que permiten comparar valores. Los operadores lógicos en SQL son los siguientes:

Hay algunos más pero éstos son los más importantes. Los dos primeros funcionan para todo tipo de valores (números, texto, fechas…), y los cuatro siguientes suelen ser útiles con variables numéricas y fechas, por ejemplo:

SELECT * FROM datos_aemet WHERE fecha < "2021-01-15"

Con ésta consulta seleccionamos todos los datos cuya fecha es anterior (menor) al 15 de Enero de 2021. En éste sentido tenemos que comentar que SQLite carece de un tipo de dato específico para fechas, por lo que las almacena en formato de texto, de modo que la fecha se pasa entre comillas. Además, conviene almacenar las fechas en formato AAAA-MM-DD, tal y como está en el comando, ya que así es más fácil ordenarlas.

También podemos recuperar las filas que contengan valores en una lista mediante el operador IN y abriendo paréntesis. Cuando las consultas empiezan a volverse algo más complejas conviene separarlas en varias líneas y cuidar la identación para que sean más fáciles de leer:

SELECT * FROM datos_aemet 
WHERE 
  fecha == "2021-01-15" 
  AND 
  estacion IN ("SOMOSIERRA", "GETAFE", "SEGOVIA")

Por supuesto, podemos invertir el operador IN para que nos devuelva las filas que NO contengan ninguno de los valores en ella mediante el NOT.

SELECT * FROM datos_aemet 
WHERE 
  fecha == "2021-01-15" 
  AND 
  estacion NOT IN ("SOMOSIERRA", "GETAFE", "SEGOVIA")

Otro de los operadores más útiles para seleccionar filas es el LIKE. Hemos visto que podemos seleccionar filas que tienen un valor exacto con SELECT * FROM tabla WHERE columna == "Valor". Pero muchas veces, no nos interesa que la coincidencia sea exacta, sino que queremos que encaje con un patrón más genérico.

Justamente ésta es la utilidad del operador LIKE. Veamos cómo podemos usarlo:

SELECT * FROM datos_aemet WHERE estacion LIKE "%aeropuerto%" AND fecha == "2021-02-01"

Ésta consulta selecciona todos los registros que pertenecen a las estaciones de los aeropuertos y a la fecha específica.

El símbolo _ significa “cualquier caracter”. Así “chic_” aceptaría las filas que contengan chico o chica, ya que la "_" acepta conincidencias con cualquiera de las opciones (aunque también aceptaría otras como chicw).

Con éstos elementos podemos seleccionar patrones de texto complejos (o fechas). Por ejemplo:

SELECT * FROM datos_aemet WHERE estacion == "ARANJUEZ" AND fecha LIKE "%-02-1_%"

Con ésta consulta seleccionamos todos los datos de la estación de Aranjuez, para las fechas de Febrero (de cualquier año, aunque en nuestro fichero únicamente hay datos de un año), y para los días 10-19 (el primer número del día debe ser un 1 pero gracias al _ el segundo puede ser cualquiera).

El operador LIKE nos permite encontrar filas que contienen un patrones de texto

ORDER BY

Otra de las cláusulas más utilizadas de SQL es ORDER BY, que como su nombre indica nos permite ordenar los resultados de las consultas. Su sintaxis general es la siguiente:

SELECT * FROM Tabla ORDER BY Columna [ASC / DESC]

Si la columna contiene una variable de texto, ordenará los resultados alfabéticamente, mientras que si especificamos una variable numérica lo hará utilizando sus valores. Por ejemplo, podemos obtener las estaciones con los días más fríos con la siguiente consulta:

SELECT estacion, tmed FROM datos_aemet WHERE tmed IS NOT NULL ORDER BY tmed ASC

Especificamos el nombre de la columna que queremos utilizar para ordenar nuestros resultados y luego si queremos podemos especificar que se ordene de forma ascendente (ASC) o descendente (DESC). Si no especificamos nada SQLite por defecto realiza las ordenaciones de forma ascendente.

En ésta consulta además hemos introducido una condición especial: tmed IS NOT NULL. Significa que únicamente quiero las filas que contengan valores para la variable tmed. Si quitamos la condición los primeros valores estarán vacíos para el campo tmed.

Podemos ordenar los resultados en función de los valores de varias variables. Además, es interesante saber que podemos ordenar los datos por columnas que no tienen por que estar incluídas en los resultados.

SELECT estacion, tmed FROM datos_aemet ORDER BY sol ASC

En éste caso ordenamos los resultados mediante la variable sol, que no está entre las columnas solicitadas.

Conclusiones

Con lo que hemos visto en éste artículo quedan cubiertas las características más utilizadas del lenguaje SQL, por lo menos en lo que se refiere a la lectura de los datos almacenados en las bases de datos relacionales. Con la cláusula SELECT podemos especificar qué columnas queremos y con el WHERE podemos filtrar las filas. De ésta manera podemos recuperar únicamente la información que necesitamos, acelerando las lecturas y ahorrando memoria al cargar nuestros datos en otros programas.

También hemos visto que podemos ordenar nuestros resultados directamente con SQL para no tener que hacerlo en la aplicación. La mayoría de lenguajes de programación no tienen muchas utilidades para trabajar con matrices de datos, pero gracias a SQL podemos manipular los datos almacenados en forma tabular sin problema.

En el futuro seguiremos viendo otras características importantes del lenguaje. Hasta entonces, espero que éste post sea útil.