Clase 0 – Introducción a Base de Datos con SQL

Introducción

📘 ¿Qué es una Base de Datos?

💻 SQL (Structured Query Language)

⚙️ Primeros Pasos con SQLite

🖥️ Consejos de Terminal (Terminal Tips)

🔍 SELECT

🔢 LIMIT

🎯 WHERE

⚠️ NULL

🧩 LIKE

📈 Rangos (Ranges)

📊 ORDER BY

🧮 Funciones Agregadas (Aggregate Functions)


¿Qué es una base de datos?
Una base de datos es una forma de organizar la información de modo que puedas realizar cuatro operaciones sobre ella:

  • crear

  • leer

  • actualizar

  • eliminar

Un sistema de gestión de bases de datos (DBMS, por sus siglas en inglés) es una forma de interactuar con una base de datos usando una interfaz gráfica o un lenguaje textual.

Ejemplos de DBMS: MySQL, Oracle, PostgreSQL, SQLite, Microsoft Access, MongoDB, etc.

La elección de un DBMS depende de factores como:

  • Costo: software propietario vs. software libre.

  • Nivel de soporte: el software libre y de código abierto como MySQL, PostgreSQL y SQLite tiene la desventaja de que debes configurar tú mismo la base de datos.

  • Peso: los sistemas más completos como MySQL o PostgreSQL son más pesados y requieren más recursos que sistemas más ligeros como SQLite.

En este curso comenzaremos con SQLite y luego avanzaremos a MySQL y PostgreSQL.


SQL

SQL significa Structured Query Language (Lenguaje de Consulta Estructurado). Es un lenguaje utilizado para interactuar con bases de datos, mediante el cual puedes crear, leer, actualizar y eliminar datos.

Algunos puntos importantes sobre SQL:

  • Es estructurado, como veremos en este curso.

  • Tiene palabras clave que se usan para interactuar con la base de datos.

  • Es un lenguaje de consulta: permite “preguntar” a los datos dentro de una base de datos.

En esta lección aprenderemos a escribir consultas SQL simples.


Preguntas

¿Existen subconjuntos de SQL?
SQL es un estándar tanto del American National Standards Institute (ANSI) como de la International Organization for Standardization (ISO). La mayoría de los DBMS admiten un subconjunto del lenguaje SQL. Por ejemplo, en SQLite usamos el subconjunto de SQL que este sistema soporta. Si quisiéramos migrar nuestro código a otro sistema como MySQL, probablemente tendríamos que cambiar parte de la sintaxis.


Primeros pasos con SQLite

Vale la pena destacar que SQLite no es algo que usemos solo para este curso, sino una base de datos utilizada en muchas aplicaciones: teléfonos, programas de escritorio y sitios web.

Consideremos ahora una base de datos de libros que han sido seleccionados para la lista larga del Premio Internacional Booker. Cada año hay 13 libros en la lista, y nuestra base contiene 5 años de estas listas.

Antes de comenzar a interactuar con esta base de datos:

  1. Inicia sesión en Visual Studio Code para CS50. Allí escribiremos y editaremos código.

  2. El entorno de SQLite ya está configurado en tu Codespace. Ábrelo en la terminal.


Consejos para la terminal

  • Para limpiar la pantalla de la terminal: Ctrl + L.

  • Para recuperar la instrucción anterior: Flecha hacia arriba.

  • Si una consulta SQL es muy larga, puedes presionar Enter y continuar en la línea siguiente.

  • Para salir de una base de datos o del entorno SQLite: .quit.


SELECT

¿Qué datos hay realmente en nuestra base de datos?
Para responder, usamos la primera palabra clave de SQL: SELECT, que nos permite seleccionar algunas (o todas) las filas de una tabla.

SELECT *
FROM "longlist";

Esto selecciona todas las filas de la tabla llamada longlist.

El resultado contiene todas las columnas y filas, lo cual puede ser mucha información. Podemos simplificar seleccionando solo una columna, por ejemplo, el título:

SELECT "title"
FROM "longlist";

Ahora vemos una lista con los títulos en esta tabla.
Pero, ¿qué pasa si queremos ver títulos y autores en los resultados de nuestra búsqueda?
Para ello, ejecutamos:

SELECT "title", "author"
FROM "longlist";

¿Es necesario usar comillas dobles (“) alrededor de los nombres de tablas y columnas?
Sí, es una buena práctica. Los nombres de tablas y columnas se llaman identificadores SQL. Las cadenas de texto usan comillas simples, para diferenciarlas de los identificadores.


¿De dónde provienen los datos de esta base?
De distintas fuentes:

  • Las listas largas (2018–2023) provienen del sitio web del Booker Prize.

  • Las calificaciones y otra información, de Goodreads.


¿Cómo sabemos qué tablas y columnas hay en una base de datos?
La estructura o esquema de la base de datos contiene esa información. Más adelante aprenderemos a obtenerlo y entenderlo.


¿SQLite 3 distingue mayúsculas de minúsculas? ¿Por qué algunas partes están en mayúsculas y otras no?
SQLite no distingue mayúsculas de minúsculas. Sin embargo, por convención:

  • Las palabras clave SQL se escriben en mayúsculas para mejorar la legibilidad.

  • Los nombres de tablas y columnas suelen ir en minúsculas.

Ejemplo:

SELECT *
FROM "longlist";

LIMIT

Si una base de datos tuviera millones de filas, no tendría sentido seleccionar todas. Podemos usar LIMIT para mostrar solo una cantidad específica de filas:

SELECT "title"
FROM "longlist"
LIMIT 10;

Esta consulta nos da los primeros 10 títulos en la base de datos. Los títulos están ordenados de la misma manera en la salida de esta consulta que en la base de datos.


WHERE

La palabra clave WHERE se utiliza para seleccionar filas basadas en una condición; producirá las filas para las cuales la condición especificada sea verdadera.

SELECT "title", "author"
FROM "longlist"
WHERE "year" = 2023;

Esta consulta nos da los títulos y autores de los libros incluidos en la lista larga en 2023. Observa que 2023 no está entre comillas porque es un número entero, no una cadena o identificador.

Los operadores que pueden usarse para especificar condiciones en SQL son = (“igual a”), != (“no igual a”) y <> (también “no igual a”).

Para seleccionar los libros que no son de tapa dura, podemos ejecutar la consulta:

SELECT "title", "format"
FROM "longlist"
WHERE "format" != 'hardcover';

Observa que hardcover está entre comillas simples porque es una cadena SQL y no un identificador.

!= puede reemplazarse con el operador <> para obtener los mismos resultados. La consulta modificada sería:

SELECT "title", "format"
FROM "longlist"
WHERE "format" <> 'hardcover';

Otra manera de obtener los mismos resultados es usar la palabra clave SQL NOT. La consulta modificada sería:

SELECT "title", "format"
FROM "longlist"
WHERE NOT "format" = 'hardcover';

Para combinar condiciones, podemos usar las palabras clave SQL AND y OR. También podemos usar paréntesis para indicar cómo combinar las condiciones en una declaración condicional compuesta.

Para seleccionar los títulos y autores de los libros incluidos en la lista larga en 2022 o 2023:

SELECT "title", "author"
FROM "longlist"
WHERE "year" = 2022 OR "year" = 2023;

Para seleccionar los libros incluidos en la lista larga en 2022 o 2023 que no fueron de tapa dura:

SELECT "title", "format"
FROM "longlist"
WHERE ("year" = 2022 OR "year" = 2023) AND "format" != 'hardcover';

Aquí, los paréntesis indican que la cláusula OR debe evaluarse antes que la cláusula AND.


NULL

Es posible que las tablas tengan datos faltantes. NULL es un tipo utilizado para indicar que ciertos datos no tienen un valor o no existen en la tabla.

Por ejemplo, los libros en nuestra base de datos tienen un traductor junto con un autor. Sin embargo, solo algunos de los libros han sido traducidos al inglés. Para los otros libros, el valor del traductor será NULL.

Las condiciones usadas con NULL son IS NULL y IS NOT NULL.

Para seleccionar los libros para los cuales no existen traductores, podemos ejecutar:

SELECT "title", "translator"
FROM "longlist"
WHERE "translator" IS NULL;

Intentemos lo contrario: seleccionar los libros para los cuales sí existen traductores:

SELECT "title", "translator"
FROM "longlist"
WHERE "translator" IS NOT NULL;

LIKE

Esta palabra clave se usa para seleccionar datos que coincidan aproximadamente con la cadena especificada. Por ejemplo, LIKE podría usarse para seleccionar libros que tengan cierta palabra o frase en su título.

LIKE se combina con los operadores % (coincide con cualquier número de caracteres alrededor de una cadena dada) y _ (coincide con un solo carácter).

Para seleccionar los libros con la palabra “love” en sus títulos, podemos ejecutar:

SELECT "title"
FROM "longlist"
WHERE "title" LIKE '%love%';

% coincide con 0 o más caracteres, por lo que esta consulta coincidiría con títulos de libros que tengan 0 o más caracteres antes y después de “love”, es decir, títulos que contengan “love”.

Para seleccionar los libros cuyos títulos comienzan con “The”, podemos ejecutar:

SELECT "title"
FROM "longlist"
WHERE "title" LIKE 'The%';

La consulta anterior también puede devolver libros cuyos títulos comiencen con “Their” o “They”. Para seleccionar solo los libros cuyos títulos comienzan con la palabra “The”, podemos agregar un espacio:

SELECT "title"
FROM "longlist"
WHERE "title" LIKE 'The %';

Dado que hay un libro en la tabla cuyo nombre es “Pyre” o “Pire”, podemos seleccionarlo ejecutando:

SELECT "title"
FROM "longlist"
WHERE "title" LIKE 'P_re';

Esta consulta también podría devolver títulos como “Pore” o “Pure” si existieran en nuestra base de datos, porque _ coincide con cualquier carácter único.


Preguntas

¿Podemos usar múltiples símbolos % o _ en una consulta?

Sí, podemos.
Ejemplo 1: si quisiéramos seleccionar libros cuyos títulos comienzan con “The” y tienen “love” en alguna parte del medio, podríamos ejecutar:

SELECT "title"
FROM "longlist"
WHERE "title" LIKE 'The%love%';

Nota: ningún libro de nuestra base de datos actual coincide con este patrón, por lo que esta consulta no devuelve nada.

Ejemplo 2: si sabemos que hay un libro en la tabla cuyo título comienza con “T” y tiene cuatro letras, podemos intentar encontrarlo ejecutando:

SELECT "title"
FROM "longlist"
WHERE "title" LIKE 'T____';

¿La comparación de cadenas distingue mayúsculas y minúsculas en SQL?

En SQLite, la comparación de cadenas con LIKE es, por defecto, insensible a mayúsculas y minúsculas, mientras que la comparación con = sí las distingue.
(Observa que, en otros DBMS, la configuración de tu base de datos puede cambiar esto).


RANGES (Rangos)

También podemos usar los operadores <, >, <= y >= en nuestras condiciones para coincidir con un rango de valores.
Por ejemplo, para seleccionar todos los libros incluidos en la lista larga entre los años 2019 y 2022 (inclusive), podemos ejecutar:

SELECT "title", "author"
FROM "longlist"
WHERE "year" >= 2019 AND "year" <= 2022;

Otra manera de obtener los mismos resultados es usar las palabras clave BETWEEN y AND para especificar rangos inclusivos. Podemos ejecutar:

SELECT "title", "author"
FROM "longlist"
WHERE "year" BETWEEN 2019 AND 2022;

Para seleccionar los libros que tienen una calificación de 4.0 o superior, podemos ejecutar:

SELECT "title", "rating"
FROM "longlist"
WHERE "rating" > 4.0;

Para limitar aún más los libros seleccionados por número de votos, y tener solo aquellos con al menos 10.000 votos, podemos ejecutar:

SELECT "title", "rating", "votes"
FROM "longlist"
WHERE "rating" > 4.0 AND "votes" > 10000;

Para seleccionar los libros que tienen menos de 300 páginas, podemos ejecutar:

SELECT "title", "pages"
FROM "longlist"
WHERE "pages" < 300;

Preguntas

Para los operadores de rango como < y >, ¿los valores en la base de datos deben ser enteros?

No, los valores pueden ser enteros o números de punto flotante (es decir, “decimales” o “reales”).
Al crear una base de datos, hay formas de establecer estos tipos de datos para las columnas.


ORDER BY

La palabra clave ORDER BY nos permite organizar las filas devueltas en un orden específico.

La siguiente consulta selecciona los 10 libros con menor calificación en nuestra base de datos:

SELECT "title", "rating"
FROM "longlist"
ORDER BY "rating"
LIMIT 10;

Observa que obtenemos los 10 libros inferiores porque ORDER BY elige el orden ascendente por defecto.

En cambio, para seleccionar los 10 libros superiores:

SELECT "title", "rating"
FROM "longlist"
ORDER BY "rating" DESC
LIMIT 10;

Observa el uso de la palabra clave SQL DESC para especificar el orden descendente.
ASC puede usarse para especificar explícitamente el orden ascendente.

Para seleccionar los 10 libros principales por calificación e incluir también el número de votos como criterio de desempate, podemos ejecutar:

SELECT "title", "rating", "votes"
FROM "longlist"
ORDER BY "rating" DESC, "votes" DESC
LIMIT 10;

Observa que para cada columna en la cláusula ORDER BY, especificamos el orden ascendente o descendente.

Preguntas

¿Podemos ordenar los libros por título alfabéticamente usando ORDER BY?
Sí, podemos. La consulta sería:

SELECT "title"
FROM "longlist"
ORDER BY "title";

AGGREGATE FUNCTIONS (Funciones Agregadas)

COUNT, AVG, MIN, MAX y SUM se llaman funciones agregadas y nos permiten realizar las operaciones correspondientes sobre múltiples filas de datos.
Por su naturaleza, cada una de las siguientes funciones agregadas devolverá solo un único resultado: el valor agregado.

Para encontrar la calificación promedio de todos los libros en la base de datos:

SELECT AVG("rating")
FROM "longlist";

Para redondear la calificación promedio a 2 decimales:

SELECT ROUND(AVG("rating"), 2)
FROM "longlist";

Para renombrar la columna en la que se muestran los resultados:

SELECT ROUND(AVG("rating"), 2) AS "average rating"
FROM "longlist";

Observa el uso de la palabra clave SQL AS para renombrar columnas.

Para seleccionar la calificación máxima en la base de datos:

SELECT MAX("rating")
FROM "longlist";

Para seleccionar la calificación mínima en la base de datos:

SELECT MIN("rating")
FROM "longlist";

Para contar el número total de votos en la base de datos:

SELECT SUM("votes")
FROM "longlist";

Para contar el número de libros en nuestra base de datos:

SELECT COUNT(*)
FROM "longlist";

Recuerda que usamos * para seleccionar cada fila y columna de la base de datos. En este caso, estamos intentando contar cada fila en la base, y por eso usamos *.

Para contar el número de traductores:

SELECT COUNT("translator")
FROM "longlist";

Observamos que el número de traductores es menor que el número de filas en la base de datos.
Esto se debe a que la función COUNT no cuenta los valores NULL.

Para contar el número de editores en la base de datos:

SELECT COUNT("publisher")
FROM "longlist";

Como con los traductores, esta consulta contará el número de valores de editor que no sean NULL.
Sin embargo, esto puede incluir duplicados.
Otra palabra clave de SQL, DISTINCT, puede usarse para asegurar que solo se cuenten valores distintos:

SELECT COUNT(DISTINCT "publisher")
FROM "longlist";

Preguntas

¿Usar MAX con la columna de título te daría el título de libro más largo?
No, usar MAX con la columna de título te daría el título “más grande” (o en este caso, el último) alfabéticamente.
De manera similar, MIN dará el primer título alfabéticamente.