Consultas SQL para manejo de fechas
Consultas SQL para manejo de fechas
EN SQL es posible sumar fechas para obtener fechas futuras. En SQLite lo podemos lograr pasando un segundo argumento a la
función DATE. Esto suena complicado pero es mas sencillo de lo que parece:
En este ejemplo, estamos sumando 1 día a la fecha de hoy (now). Si queremos sumar más días, por ejemplo 5 días,
utilizaremos DATE('now', '5 day').
Ejercicio
Se tiene una tabla de tareas con los campos id, descripcion y fecha_limite. Se pide seleccionar todos los campos de las tareas que
tienen como fecha límite el día de mañana.
Respuesta: select * from tareas where date ('now', '1 day') limit 3
Es importante aclarar que cuando no especificamos el signo, se asume que es positivo, esto quiere decir que
es lo mismo que
Ejercicio
Supongamos que tenemos una tabla llamada ganancias con las columnas "id" (identificador único), "fecha" (fecha de registro) y
"monto" (ganancia del día).
Muestra el monto correspondiente al día de ayer.
Respuesta: SELECT monto FROM ganancias WHERE fecha = strftime('%Y-%m-%d', 'now', '-1 day')
Para ciertos reportes, es muy probable que nos pidan extraer información de una fecha, como, por ejemplo, el año en que se hizo una
transacción.
1 200 2010-01-15
2 150 2011-02-20
3 300 2012-03-10
4 250 2013-04-05
ID_VENT MONT FECHA_VEN
A O TA
5 100 2014-05-25
6 350 2015-06-18
7 400 2015-07-22
8 180 2015-08-09
9 220 2018-09-30
10 275 2019-10-11
Nos piden mostrar toda la información de la tabla y adicionalmente agregar una columna con el año de la venta.
SELECT *, strftime('%Y', fecha_venta) as año_venta FROM ventas El resultado de esta consulta será el siguiente:
Para mostrar los resultados de este tipo de funciones, es necesario asignar un nombre a la nueva columna, ya que, de lo contrario, la
columna resultante mantendrá el nombre de "strftime('%Y', fecha_venta)", lo cual resultaría en una denominación poco legible para un
informe.
Ejercicio
Dada una tabla ventas con las columnas monto y fecha_venta, crea una consulta que muestre únicamente el de la venta. La columna
que muestre el año de la venta debe llamarse año_venta
Podemos extraer el mes de una fecha de manera similar a la extracción del año, utilizando nuevamente la función strftime.
Siguiendo con nuestro ejemplo de la tabla de ventas, si deseamos agregar una columna que indique únicamente el mes de la venta,
podemos utilizar la siguiente consulta:
1 200 2010-01-15
2 150 2011-02-20
3 300 2012-03-10
4 250 2013-04-05
ID_VENT MONT FECHA_VEN
A O TA
5 100 2014-05-25
6 350 2015-06-18
7 400 2015-07-22
8 180 2015-08-09
9 220 2018-09-30
10 275 2019-10-11
En este caso, para obtener el mes, pasamos %m como argumento a la función strftime.
Ejercicio
Dada la tabla ventas previamente presentada con las columnas monto y fecha_venta, crea una consulta que muestre una tabla con el
monto, el mes de la venta y el año de la venta, en ese mismo orden. La columna para el mes de la venta debe llamarse mes_venta y
aquella para el año de la venta debe llamarse año_venta
SELECT monto, strftime('%m', fecha_venta) as mes_venta, strftime('%Y', fecha_venta) as año_venta
FROM ventas
Ya aprendimos a extraer el mes y el año de una fecha. Sin embargo, cómo podriamos extraer ambos datos en una sola columna?
Para extraer tanto el mes como el año de una fecha en una sola columna, puedes utilizar la función strftime('%Y-%m'). Esto te permitirá
obtener un resultado en el formato "año-mes". Veamos un ejemplo utilizando una tabla de ventas:
Ejercicio
Dada la tabla ventas con las columnas monto y fecha_venta, crea una consulta que muestre las siguientes dos columnas:
Monto
El mes y año de la fecha de venta. Esta columna debe llamarse año_mes
1 200 2010-01-15
ID_VENT MONT FECHA_VEN
A O TA
2 150 2011-02-20
3 300 2012-03-10
4 250 2013-04-05
5 100 2014-05-25
6 350 2015-06-18
7 400 2015-07-22
8 180 2015-08-09
9 220 2018-09-30
10 275 2019-10-11
Extracciones y where
Previamente aprendimos a filtrar utilizando como parámetro una fecha. Ahora utilizaremos lo aprendido para filtrar fechas de un año o
mes en específico.
1 200 2010-01-15
2 150 2011-02-20
3 300 2012-03-10
4 250 2013-04-05
5 100 2014-05-25
6 350 2015-06-18
7 400 2015-07-22
8 180 2015-08-09
9 220 2018-09-30
ID_VENT MONT FECHA_VEN
A O TA
10 275 2019-10-11
Nos piden mostrar todas las ventas del año 2012. Para esto utilizaremos la función strftime para extraer el año de las fechas, y luego
filtraremos por el año indicado:
Ejercicio
Dada una tabla ventas con las columnas monto y fecha_venta, selecciona toda la información de las ventas del 2015
En SQL hay funciones que nos permiten ejecutar operaciones sobre un conjunto de resultados. Estas reciben el nombre de funciones
de agregación.
En este ejercicio trabajaremos con la función MAX() la cual nos permite encontrar el valor más alto del campo que especifiquemos.
Una consulta con la función max se ve de la siguiente forma:
Por ejemplo, se tiene una tabla llamada empleados con los siguientes datos:
Ejercicio
Utilizando los mismos datos previos selecciona la mayor edad de la tabla empleados
Tip: Aunque en SQL es válido escribir tanto MAX (columna) como MAX(columna), el corrector de ejercicios considerará la primera
opción como incorrecta debido al espacio adicional. Por lo tanto, escribe la función sin espacios.
MAX()
MIN()
En este ejercicio introduciremos la función de agregación SUM(). Con esta podemos sumar todos los elementos de una columna.
Ejercicio
MAX()
MIN()
SUM()
En este ejercicio aprenderemos a calcular promedios con la función de agregación AVG(). El nombre de la función viene del término en
inglés average
Ejercicio
MAX()
MIN()
SUM()
AVG()
Ahora introduciremos la función de agregación COUNT(). Con esta podemos contar la cantidad de registros dentro de una tabla.
Ejercicio
Las funciones de agregación se pueden combinar con las claúsulas previamente estudiadas. Simplemente tenemos que respetar el
orden establecido de las claúsulas.
A la hora de extraer datos de base de datos será muy común que utilicemos las funciones de agregación en conjunto con where.
Utilizando la tabla empleados, calcula la suma de sueldos de todas las personas mayores a 27 años.
Distinct
En SQL el keyword DISTINCT nos permite filtrar los resultados repetidos de una consulta.
Rojo
Azul
Verde
Amarillo
Rojo
Verde
Rojo
Verde
Rojo
Negro
Blanco
Rojo
Azul
COLOR
Verde
Amarillo
Nos piden crear una consulta que nos muestre cada color una única vez. Para esto utilizaremos la siguiente consulta
Ejercicio
Prueba en el editor la misma instrucción aprendida para ver cual sería el resultado de la consulta.
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
CORREO
[Link]@[Link]
[Link]@[Link]
Crea una consulta que nos muestre cada correo una única vez. La columa mostrada debe llamarse correo_unico
1 200 2010-01-15
2 150 2011-02-20
3 300 2012-04-10
ID_VENT MONT FECHA_VEN
A O TA
4 250 2013-04-05
5 100 2014-04-25
6 350 2015-06-18
7 400 2015-06-22
8 180 2015-06-09
9 220 2018-07-30
10 275 2019-07-11
Se nos ha solicitado crear una consulta que muestre los años en los que se han realizado transacciones, excluyendo repeticiones.
Como ya aprendimos en ejercicios anteriores, para obtener el año a partir de la fecha de venta, podemos utilizar el siguiente código:
Sin embargo, para asegurarnos de obtener años únicos, podemos agregar la cláusula DISTINCT a nuestra consulta de la siguiente
manera:
SELECT DISTINCT strftime('%Y', fecha_venta) as año_unico FROM ventas
Ejercicio
Utilizando la misma tabla de ventas previamente utilizada, selecciona todos los meses distintos, asignándole a la columna el alias
"mes_unico".
Si queremos contar los valores distintos en una columna de una tabla, podemos combinar las funciones COUNT y DISTINCT de la
siguiente manera:COUNT(DISTINCT columna)
E O O O
E O O O
Humanos
E O O O
Ejercicio
Crea una consulta que muestre los teléfonos únicos de la tabla. La columna mostrada debe llamarse telefonos_unicos
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
CORREO
[Link]@[Link]
[Link]@[Link]
Crea una consulta para contestar cuantos correos únicos existen en la tabla. La columna resultante debe llamarse correos_cant
Podemos usar DISTINCT con más de una columna para obtener combinaciones únicas de esas columnas. Supongamos que tienes una
tabla llamada empleados con las columnas departamento y puesto.
3 Carlos IT Desarrollador
4 Ana IT Desarrollador
6 Carmen IT Gerente
7 José IT Desarrollador
Luego podemos obtener todas las combinaciones únicas de Departamento y Puesto utilizando la siguiente consulta:
Ventas Vendedor
IT Desarrollador
Ventas Gerente
IT Gerente
Ejercicio
Para la siguiente tabla "productos" deseamos obtener todas las combinaciones únicas de "Categoria" y "Precio"
CATEGORI PRECI
NOMBRE
A O
Camiseta Ropa 20
Pantalón Ropa 40
CATEGORI PRECI
NOMBRE
A O
Auriculares Electrónica 50
Libro Libros 15
Mochila Accesorios 30
La cláusula GROUP BY es una poderosa herramienta en SQL que se utiliza para agrupar filas con valores idénticos en una o varias
columnas específicas, permitiendo realizar operaciones de agregación en cada grupo.
En este primer ejercicio aprenderemos a utilizar GROUP BY para obtener todos los elementos distintos de una tabla, lo mismo que
previamente hicimos con distinct.
Rojo
Azul
Verde
Amarillo
Naranja
Morado
Rosa
Café
Gris
Negro
COLOR
Blanco
Rojo
Azul
Verde
Amarillo
COLOR
Amarillo
COLOR
Azul
Blanco
Café
Gris
Morado
Naranja
Negro
Rojo
Rosa
Verde
Ejercicio
CORREO
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
CORREO
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
Crea una consulta que nos muestre cada correo una única vez. La columa mostrada debe llamarse correo_unico
Agrupar y contar
GROUP BY es comúnmente utilizada junto con funciones de agregación como COUNT, MAX, MIN, SUM y AVG para obtener
información resumida de un conjunto de datos.
COLOR
Rojo
Azul
Verde
Amarillo
Naranja
Morado
Rosa
Café
Gris
COLOR
Negro
Blanco
Rojo
Azul
Verde
Amarillo
Queremos saber cuantas veces aparece cada color. Esto lo podemos lograr combinando GROUP BY y la función de agregación
COUNT
Amarillo 2
Azul 2
Blanco 1
Café 1
Gris 1
Morado 1
Naranja 1
Negro 1
Rojo 2
Rosa 1
REPETICION
COLOR
ES
Verde 2
Ejercicio
CORREO
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
CORREO
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
Crea una consulta que nos muestre cada correo una única vez junto a la cantidad de repeticiones. Las columnas deben llamarse correo
y repeticiones.
Se pide contar cuantas personas trabajan en cada departamento. Las columnas resultantes deben llamarse departamento y
cantidad_empleados
Agrupar y sumar
En este ejercicio agruparemos y sumaremos. La lógica de la consulta es la misma previamente mencionada, solo cambia la funcion de
agrupacion a utilizar. Por ejemplo, tenemos la tabla pedidos con los siguientes datos:
CLIENT MONT
E O
Cliente A 1200
Cliente A 800
Cliente B 150
Cliente C 200
Cliente B 90
Si queremos calcular cuanto ha gastado cada cliente, podemos realizar la siguiente consulta
Ejercicio
Utilizando la siguiente tabla ventas de una empresa, crea una consulta que muestre cuanto se vendió en total por cada cateogría. Las
columnas de la consulta deben llamarse categoria y monto_total
PRODUCT MONT
CATEGORIA
O O
Mesa de 90 Mobiliario
Café
Bolso de 70 Accesorios
Viaje
Camisa 40 Ropa
Casual
PRODUCT MONT
CATEGORIA
O O
Licuadora 60 Electrodomésticos
Max
Libro de 20 Libros
Cocina
Novela 15 Libros
Misterio
Audífonos 50 Electrónicos
Plus
Lámpara 45 Mobiliario
Moderna
Bolso de 70 Accesorios
Viaje
Agrupar y promediar
Previamente aprendimos que AVG nos permite calcular el promedio de los elementos de una columna en una tabla. En este ejercicio lo
utilizaremos para calcular promedios por grupo.
Ejercicio
Juan Pérez 7
Juan Pérez 8
Juan Pérez 6
María Rodríguez 9
María Rodríguez 7
María Rodríguez 8
Carlos García 6
Carlos García 5
Carlos García 7
Ana Fernández 8
Ana Fernández 9
Ana Fernández 8
Luis Morales 7
NOMBRE_COMPLETO NOTA
Luis Morales 6
Luis Morales 5
Encuentra el promedio de notas de cada estudiante. Las columnas deben tener el nombre de Nombre_Completo y Promedio_Notas
respectivamente.
Este ejercicio tiene un supuesto importante: que no hay dos estudiantes con el mismo nombre y apellido. Discutiremos este tipo de
supuestos más adelante cuando revisemos el concepto de integridad.
En este ejercicio combinaremos la función de agregación MAX() con group by para poder obtener el monto mas alto de cada grupo. La
sintaxis de la consulta será igual a las vistas previamente, es decir:
Ejercicio
Dada la siguiente tabla de ventas:
PRODUCT MONT
CATEGORIA
O O
Mesa de 90 Mobiliario
Café
Bolso de 70 Accesorios
Viaje
Camisa 40 Ropa
Casual
Licuadora 60 Electrodomésticos
Max
Libro de 20 Libros
Cocina
Novela 15 Libros
Misterio
Audífonos 50 Electrónicos
Plus
Lámpara 45 Mobiliario
Moderna
PRODUCT MONT
CATEGORIA
O O
Bolso de 70 Accesorios
Viaje
Crea una consulta para calcular el monto mas alto por cada categoría. La tabla resultante debe tener dos
columnas: categoria y monto_mas_alto.
En este ejercicio combinaremos la función MIN() con GROUP BY para poder obtener el monto mas bajo de cada [Link] sintaxis de
la consulta será igual a las vistas previamente, es decir:
PRODUCT MONT
CATEGORIA
O O
Mesa de 90 Mobiliario
Café
Bolso de 70 Accesorios
Viaje
Run
Camisa 40 Ropa
Casual
Licuadora 60 Electrodomésticos
Max
Libro de 20 Libros
Cocina
Novela 15 Libros
Misterio
Audífonos 50 Electrónicos
Plus
Lámpara 45 Mobiliario
PRODUCT MONT
CATEGORIA
O O
Moderna
Bolso de 70 Accesorios
Viaje
Crea una consulta para calcular el monto más bajo por cada categoría. La tabla resultante debe tener dos
columnas: categoria y monto_mas_bajo.
A la hora de construir informes, frecuentemente necesitaremos entregar información agrupada en un periodo de tiempo. Para lograr
esto utilizaremos una combinación de GROUP BY con la función strftime.
Tenemos la tabla "ventas" con la siguiente información:
1 200 2010-01-15
2 150 2011-02-20
3 300 2012-03-10
4 250 2012-04-05
5 100 2014-05-25
6 350 2015-06-18
7 400 2015-07-22
8 180 2015-08-09
9 220 2018-09-30
10 275 2018-10-11
Se nos solicita determinar el monto total de ventas por año. Para resolverlo tenemos que agrupar por fecha y sumar los montos de la
siguiente forma:
SELECT SUM(monto), strftime("%Y", fecha_venta) AS año FROM ventas GROUP BY strftime("%Y", fecha_venta)
Ejercicio
1 200 2010-01-15
2 150 2010-02-20
3 300 2010-02-10
4 250 2010-04-05
5 100 2010-04-25
6 350 2010-04-18
7 400 2010-06-22
ID_VENT MONT FECHA_VEN
A O TA
8 180 2010-06-09
9 220 2010-09-30
10 275 2010-10-11
Calcula el total de ventas por mes. El nombre de las columnas resultantes será "suma_ventas" y "mes" respectivamente.
SELECT SUM(monto) AS suma_ventas, strftime("%m", fecha_venta) AS mes FROM ventas GROUP BY mes
Se tiene una tabla llamada inscripciones con distintas fechas de inscripciones de un usuario a un sitio web.
FECHA_INSCRIPCI
ON
2022-01-15
2022-01-20
2022-02-10
2022-02-05
2022-03-25
2022-03-18
2022-04-22
2022-04-09
2022-05-30
2022-05-11
2022-06-19
2022-06-29
FECHA_INSCRIPCI
ON
2022-07-12
2022-07-21
2022-08-08
2022-08-17
2022-09-13
2022-09-26
2022-10-14
2022-10-28
Cuenta cuántos usuarios se registraron cada mes. Las columnas resultantes deben llamarse "mes" y "cantidad_usuarios".
Cuando se trata de agrupar datos en una consulta SQL, existe una forma de evitar la redundancia de la cláusula SELECT. Por ejemplo,
considera la siguiente consulta:
SELECT strftime("%Y", fecha_venta) AS año, SUM(monto) FROM ventas GROUP BY strftime("%Y", fecha_venta)
Esta notación se interpreta como "agrupa por el primer criterio". También es posible aplicar esta sintaxis en la cláusula ORDER BY:
De esta manera, puedes lograr la misma agrupación y ordenamiento sin repetir la expresión de la cláusula SELECT.
Ejercicio
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
CORREO
[Link]@[Link]
[Link]@[Link]
Crea una consulta que nos muestre cada correo una única vez acompañado del número de veces que se repite. Las columnas deben
llevar los nombres "correo" y "repeticiones", respectivamente, y deben estar ordenadas alfabéticamente
Y como aprendimos en el ejercicio anterior, también podemos escribir la consulta de la siguiente manera:
Ejercicio
Tenemos la siguiente tabla estudiantes
NOT
CORREO MATERIA
A
Calcula el promedio de cada estudiante en cada materia. Las columnas deben llamarse correo, materia y promedio_notas
Introducción a Having
En SQL, la cláusula GROUP BY nos permite agrupar datos. Si queremos filtrar la información obtenida utilizaremos HAVING.
HAVING se emplea para filtrar los resultados de una consulta que involucra funciones agregadas. En otras palabras, HAVING permite
aplicar condiciones de filtrado a los resultados de funciones como COUNT, MAX, MIN, SUM y AVG después de que se han
agrupado los datos con la cláusula GROUP BY.
2022-01-15
2022-01-20
2022-02-10
2022-02-05
2022-03-25
2022-03-18
2022-04-22
2022-04-09
2022-05-30
2022-05-11
2022-06-19
2022-06-29
FECHA_INSCRIPCI
ON
2022-07-12
2022-07-21
2022-08-08
2022-08-17
2022-09-13
2022-09-26
2022-10-14
2022-10-28
Nos piden crear un reporte mostrando los meses y la cantidad de inscritos, pero solo donde hayan 2 o más inscritos.
Ejercicio
Crea un reporte mostrando los meses y la cantidad de inscritos pero solo donde haya 1 inscrito. Las columnas deben llamarse mes y
cantidad_usuarios respectivamente.
Buscando duplicados
Uno de los usos mas recurrentes de HAVING es buscar duplicados. Por ejemplo, dada una tabla de correos ver cuales están más de 1
vez.
Ejercicio
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
[Link]@[Link]
CORREO
[Link]@[Link]
[Link]@[Link]
Muestra los correos que aparezcan en más de una ocasión. La tabla resultante debe tener dos columnas: una llamada correo, y otra
llamada cuenta_correos que muestra la cantidad de repeticiones correspondiente a cada correo.
Having y cuenta
Ejercicio
Crea una consulta que muestre la cantidad de usuarios y el departamento en donde haya más de un empleado. Las columnas deben
llamarse cantidad_de_usuarios y departamento, respectivamente.
Having y promedio
Ejercicio
Alumno1@[Link] 90
Alumno1@[Link] 50
Alumno1@[Link] 30
Alumno2@[Link] 90
Alumno2@[Link] 20
Alumno3@[Link] 80
Alumno2@[Link] 50
Alumno3@[Link] 30
Alumno3@[Link] 10
Crea una consulta para determinar cuales son los estudiantes que aprobaron. El criterio de aprobación es promedio de notas >= 50.
SELECT email, avg(notas) AS promedio_notas FROM notas GROUP BY email HAVING promedio_notas >= 50
Having y order
Una vez que hemos agrupado datos utilizando la cláusula GROUP BY, es común que necesitemos ordenar esos grupos según algún
criterio específico. Por lo general, queremos ordenar los grupos en función de alguna métrica agregada, como la suma, el conteo, el
promedio, etc. Para hacer esto, usamos la cláusula ORDER BY junto con las funciones de agregación.
resultado.
4 GROUP Agrupa
BY registros por
una o más
columnas.
ORDE CLAUSUL DESCRIPCIÓ
N A N
7 LIMIT Limita el
número de
registros
retornados.
Ejercicio
Dada la siguiente tabla ventas, escribe una consulta SQL para obtener los productos que se han vendido en una cantidad total mayor a
1000, ordenados en orden descendente de cantidad vendida.
PRODUCT CANTIDA
O D
A 500
B 2000
C 300
D 1500
E 700
A 600
B 800
C 1200
D 400
E 300
Supongamos que tienes una tabla de empleados con los siguientes datos:
Tu tarea es escribir una consulta SQL que devuelva los departamentos cuyo salario promedio es mayor a 3000, ordenados de mayor a
menor salario promedio. Los resultados deben mostrar el nombre del departamento y el salario promedio, con los nombres de las
columnas como Departamento y Salario_Promedio
SELECT departamento, AVG(salario) AS Salario_Promedio FROM empleados GROUP BY departamento HAVING
Salario_Promedio > 3000 ORDER BY Salario ASC
Tu resultado
DEPARTAMENT SALARIO_PROMED
O IO
Ventas 3400
Marketing 3150
Introduccion a subconsultas
Las subconsultas, también conocidas como "subqueries", nos permiten utilizar los resultados de una consulta dentro de otra consulta.
Se nos pide seleccionar a todas las personas que ganan sobre el promedio.
Ejercicio
Utilizando los mismos datos de la tabla empleados, selecciona todos los registros cuyo sueldo sea menor o igual al promedio.
SELECT * FROM empleados WHERE sueldo <= (SELECT AVG(sueldo) FROM empleados)
Tu resultado
NOMBR APELLID SUELD DEPARTAMENT
E O O O
Dentro de las subconsultas, podemos utilizar las mismas cláusulas que hemos aprendido hasta ahora, como la cláusula WHERE. Esto
significa que podemos aplicar la cláusula WHERE tanto dentro de la subconsulta como fuera de ella.
Ejercicio
Selecciona toda la información de los registros que sean mayores al promedio del departamento de finanzas.
Tip:
Se pide el promedio exclusivamente del departamento de finanzas por lo que no hay necesidad de agrupar los datos.
Para este tipo de problema usualmente hay más de una solución.
SELECT * FROM empleados WHERE sueldo > (SELECT AVG(sueldo) FROM empleados WHERE departamento
= 'Finanzas')
Tu resultado
NOMBR APELLID SUELD DEPARTAMENT
E O O O
SELECT * FROM empleados WHERE sueldo > (SELECT MAX(sueldo) FROM empleados WHERE departamento =
'Finanzas')
Tu resultado
E O O O
NOTA
EMAIL
S
Alumno1@[Link] 90
Alumno2@[Link] 90
Alumno3@[Link] 80
Subconsultas con IN
El operador IN es un operador muy útil en subconsultas. Para entenderlo, primero probaremos una consulta sencilla utilizandolo
directamente sin subconsultas.
CÓDIGO
PAÍS TELÉFON
O
Argentina +54
CÓDIGO
PAÍS TELÉFON
O
Brasil +55
Chile +56
Colombia +57
España +34
Estados +1
Unidos
México +52
Queremos seleccionar todos los códigos de Argentina, Brasil, Chile o Colombia. Una forma de abordar el problema sería combinar
todas las opciones con where y múltiples operadores or. Otra opción es utilizando el operador IN de la siguiente manera:
SELECT *
FROM paises
WHERE pais IN ('Argentina', 'Brasil', 'Chile', 'Colombia')
ESTUDIANTE_I NOMBR
D E
1 Juan
2 María
3 Pedro
4 Ana
y la tabla de notas
ESTUDIANTE_I PROMEDIO_NOT
D AS
1 85
ESTUDIANTE_I PROMEDIO_NOT
D AS
2 65
3 49
4 38
Se nos pide mostrar los nombres de todas las personas que tengan un promedio de notas menor que 50.
Ejercicio
ESTUDIANTE_I NOMBR
D E
1 Juan
ESTUDIANTE_I NOMBR
D E
2 María
3 Pedro
4 Ana
Y se tiene una tabla promedios con el código del estudiante y su promedio de notas.
ESTUDIANTE_I PROMEDIO_NOT
D AS
1 85
2 65
3 49
4 38
Muestra los nombres de todos los estudiantes que tengan un promedio de notas sobre 50
Tip 1: No necesitas agrupar ni promediar ni contar Tip 2: Hay más de una forma de resolver este ejercicio, no te adelantes a joins e
intenta resolverlo utilizando subqueries
SELECT NOMBRE FROM ESTUDIANTES WHERE ESTUDIANTE_ID IN (SELECT ESTUDIANTE_ID FROM PROMEDIOS WHERE
PROMEDIO_NOTAS > 50)
Tu resultado
NOMBR
E
Juan
María
LIBRO_I NOMBR
D E
1 La Odisea
LIBRO_I NOMBR
D E
2 Cien
Años de
Soledad
3 El
Principito
4 Moby
Dick
LIBRO_I VALORACION_PROME
D DIO
1 4.5
2 4.7
3 4.2
LIBRO_I VALORACION_PROME
D DIO
4 3.9
Crea una consulta que muestre todos los títulos con valoración_promedio > 4. La columna resultante debe llamarse
nombres_seleccionados.
SASELECT nombre AS nombres_seleccionados FROM libros WHERE libro_id IN (SELECT libro_id FROM
valoraciones WHERE valoracion_promedio > 4)
Tu resultado
NOMBRES_SELECCIONA
DOS
La Odisea
El Principito
PACIENTE_ID NOMBRE
1 Roberto
2 Carmen
3 Luisa
4 Esteban
PACIENTE_ID FECHA_CONSULTA
1 2023-05-10
2 2023-05-15
3 2023-05-20
4 2023-05-25
Se pide obtener los nombres de todos los pacientes que tuvieron su última consulta antes del 16 de mayo de 2023. La columna se debe
llamar nombres_pacientes.
SELECT nombre AS nombres_pacientes FROM pacientes WHERE paciente_id IN (SELECT paciente_id FROM
consultas WHERE fecha_consulta limit 2)
Tu resultado
NOMBRES_PACIENT
ES
Roberto
Carmen
1. Categorías
2.
Subconsultas en el FROM
Las subconsultas, también conocidas como "subqueries", nos permiten utilizar los resultados de una consulta dentro de otra consulta.
En los ejercicios anteriores utilizamos las subconsultas dentro de la claúsula WHERE, pero también es posible utilizarlas dentro de
otras claúsulas. En este ejercicio abordaremos como utilizarla dentro de FROM
SELECT *
FROM (
En este caso no parece tan útil ya que simplemente estamos seleccionando lo mismo, pero veamos un caso donde si sería necesario.
Se tiene la tabla ventas que tiene el código de vendedor y el monto de cada venta realizada. Nos piden saber cuanto es el promedio
total vendido.
EMPLEADO_ MONT
ID O
1 100
1 150
2 200
2 250
3 300
3 350
4 400
Para esto primero necesitamos sumar los montos por vendedor y luego sobre estos resultados sacamos el promedio de las ventas.
FROM (
GROUP BY empleado_id
Si queremos saber los promedios, primero tenemos que saber los totales, para eso necesitamos sumar por empleado.
FROM ventas
GROUP BY empleado_id
EMPLEADO_ TOTAL_VEN
ID TA
1 250
EMPLEADO_ TOTAL_VEN
ID TA
2 450
3 650
4 400
FROM (
FROM ventas
GROUP BY empleado_id)
Este tipo de ejercicio suele ser un poco mas complejo de pensar y escribir y requiere de cierta práctica dominar, por lo mismo el primer
ejercicio consistirá en escribir el mismo query. Intenta hacerlo sin mirar la respuesta.
Ejercicio
Se tiene la tabla ventas que tiene el código de vendedor y el monto de la venta. Nos piden saber cuanto es el promedio total vendido. El
resultado debe estar en la columna promedio_ventas.
1 Juan 2
1 Juan 1
2 María 1
2 María 1
3 Pedro 3
4 Ana 1
PROMEDIO_GOL
ES
2.25
El operador UNION en SQL se utiliza para combinar el resultado de dos o más SELECT en un solo conjunto de resultados.
Las columnas que se seleccionan en los SELECT deben tener los mismos nombres de columna, secuencia y tipos de datos.
Veamos un ejemplo:
Supongamos que tenemos dos tablas: 'Estudiantes' y 'Profesores', que contienen una lista de apellidos en cada una. Queremos crear una
lista que combine los apellidos de ambas tablas.
Estudiantes
I NOMBR APELLID
D E O
1 Juan Rodríguez
2 María Sánchez
3 Pedro Castillo
Profesores
I NOMBR APELLID
D E O
1 Alberto Vargas
2 Carla Garrido
3 Diego Mendoza
Al hacer la consulta:
SELECT apellido
FROM Estudiantes
UNION
SELECT apellido
FROM Profesores;
APELLID
O
Rodríguez
Sánchez
Castillo
Vargas
Garrido
Mendoza
Ejercicio
Juan
Maria
Pedro
y profesores
NOMBR
E
Carlos
Ana
Luis
Escribe una consulta SQL que use UNION para combinar los nombres de ambas tablas. La columna resultante debe llamarse
'nombres'.
NOMBRE
S
Ana
Carlos
Juan
Luis
Maria
Pedro
Ejercicio
Crea una consulta que nos muestre cada correo una única vez. La columna mostrada debe llamarse correos_unicos
jorgemartinez@[Link]
juanperez@[Link]
luciasanchez@[Link]
mariagarcia@[Link]
pedrolopez@[Link]
En los ejercicios anteriores aprendimos que el operador UNION se utiliza para combinar los resultados de dos o más consultas
SELECT en un solo conjunto de resultados, eliminando las filas duplicadas.
Si queremos obtener las filas duplicadas en el resultado, utilizaremos el operador UNION ALL.
Por ejemplo, si tenemos dos tablas, 'tabla1' y 'tabla2', con los siguientes datos:
tabla1
NOMBR EDA
E D
Juan 30
Maria 25
Carlos 40
tabla2
NOMBR EDA
E D
Juan 30
Luis 30
Carmen 25
NOMBR EDA
E D
Juan 30
Maria 25
Carlos 40
Juan 30
Luis 30
Carmen 25
Ejercicio
empleados1
NOMBR APELLID EDA
E O D
Juan Pérez 30
María González 25
Carlos Rodríguez 40
empleados2
Ana Martínez 22
María González 25
Carmen López 25
Crea una consulta que combine ambas tablas incluyendo las filas duplicadas.
Juan Pérez 30
María González 25
Carlos Rodríguez 40
Ana Martínez 22
María González 25
Carmen López 25
Introducción a intersección
El operador INTERSECT se utiliza para combinar dos SELECT y devolver los resultados que se encuentran en ambas consultas.
Tabla clientes1:
NOMBR
E
Juan
Maria
Carlos
Ana
Luis
Tabla clientes2:
NOMBR
E
Ana
Luis
Pedro
Carmen
NOMBR
E
Juan
NOMBR
E
Ana
Juan
Luis
Ejercicio
Dadas las siguientes tablas, lista1 y lista2, encuentra los clientes que están en ambas listas.
Lista1:
CLIENT
E
Juan
Maria
Carlos
Ana
Luis
Pedro
Carmen
Lista2:
CLIENT
E
Ana
CLIENT
E
Luis
Pedro
Carmen
Juan
Maria
Sofia
SELECT cliente FROM lista1 INTERSECT SELECT cliente FROM lista2
Tu resultado
CLIENT
E
Ana
Carmen
Juan
CLIENT
E
Luis
Maria
Pedro
El operador Except
El operador EXCEPT en SQL se utiliza para devolver todas las filas en la primera consulta que no están presentes en la segunda
consulta. En otras palabras, EXCEPT devuelve solo las filas, que son parte de la primera consulta pero no de la segunda consulta.
Por ejemplo, si tenemos dos tablas, 'Tabla1' y 'Tabla2', que contienen los siguientes datos:
Tabla1
I NOMBR
D E
1 Juan
2 María
I NOMBR
D E
3 Carlos
Tabla2
I NOMBR
D E
1 Juan
4 Ana
5 Luis
Podemos usar EXCEPT para encontrar los nombres que están en 'Tabla1' pero no en 'Tabla2' con la siguiente consulta:
María
Carlos
Ejercicio
Dadas las siguientes tablas, 'empleados' y 'gerentes', que contienen los siguientes datos:
empleados
I NOMBR
D E
1 Juan
2 María
3 Carlos
4 Ana
5 Luis
gerentes
I NOMBR
D E
1 Juan
2 María
Crea una consulta que muestre los nombres de los empleados que no son gerentes.
NOMBR
E
Ana
Carlos
Luis
La instrucción INSERT la acompañaremos de las palabra clave INTO para especificar en qué tabla queremos insertar un valor
y VALUES para especificar los valores que queremos insertar.
Por ejemplo. Si tenemos una tabla llamada productos con las columnas id, nombre y precio, podemos agregar un nuevo producto a la
tabla usando utilizando:
Para cada columna en la tabla debemos ingresar los valores correspondientes en el mismo orden en que se definen en la sentencia.
Debemos utilizar comillas simples para valores de tipo de datos de texto.
Ejercicio
Dada la tabla usuarios con las columnas id, nombre, apellido, email y telefono:
TIPO
COLUMN
DE
A
DATO
id INTEGE
TIPO
COLUMN
DE
A
DATO
nombre TEXT
apellido TEXT
email TEXT
telefono TEXT
id: 7
nombre: Lucía
apellido: Sánchez
email: luciasanchez@[Link]
telefono: 555-5555
INSERT INTO usuarios VALUES (7, 'Lucía', 'Sánchez', 'luciasanchez@[Link]', '555-5555');
Tu resultado
id INT
nombre VARCHA
R
precio INT
stock INT
id: 7
nombre: Bolso
Precio: 1000
Stock: 10
1 Camisa 50 20
2 Pantalón 80 15
3 Zapatos 120 10
4 Sombrero 30 5
7 Bolso 1000 10
A la hora de insertar datos, si hay un valor que no conocemos, o es un valor que no queremos especificar, podemos ingresar un valor
nulo.
COLUMN
TIPO
A
id INT
COLUMN
TIPO
A
nombre VARCHA
R
precio INT
stock INT
Ejercicio
COLUMN
TIPO
A
id INT
COLUMN
TIPO
A
nombre VARCHA
R
precio INT
stock INT
id: 7
nombre: Bolso
Precio: 1000
1 Camisa 50 20
2 Pantalón 80 15
3 Zapatos 120 10
4 Sombrero 30 5
7 Bolso 1000
A la hora de insertar datos es posible mencionar específicamente las columnas que se van a insertar, en lugar de mencionar todos los
valores en el orden en que se definen en la tabla.
Veamos un ejemplo:
id INT
nombre VARCHA
precio INT
stock INT
Se pide insertar un nuevo producto con los siguientes datos, pero especificando las columnas
id: 7
nombre: Bolso
Precio: 1000
Stock: 10
INSERT INTO productos (id, precio, nombre, stock) VALUES (7, 1000,'Bolso', 10);
Una ventaja de este método es que no es necesario ingresar los valores en el mismo orden en que se definen en la tabla.
Ejercicio
TIPO
COLUMN
DE
A
DATO
id INTEGE
nombre TEXT
apellido TEXT
email TEXT
telefono TEXT
Prueba agregando los siguientes datos a la tabla usuarios, puedes notar que tienen el orden alterado en relación a la tabla.
id: 7
apellido: Sánchez
nombre: Lucía
telefono: 333-3333
email: luciasanchez@[Link]
insert into usuarios (id, nombre, apellido, telefono, email) VALUES (7, 'Lucía','Sánchez',
'333-3333', 'luciasanchez@[Link]');
Tu resultado
COLUMN
TIPO
A
nombre TEXT
precio INT
stock INT
Podemos ingresar el producto "Gorro" con un precio de 1000 y dejar el stock en nulo de la siguiente manera:
Mas adelante aprenderemos que algunas columnas pueden tener restricciones que no permiten valores nulos.
Ejercicio
Tu resultado
Gorro 1000 5
Camiseta 500 10
Pantalón 1500 8
Zapatos 2000 3
Bufanda 800 12
Bolso 10
Añadir fecha de hoy a un registro
Si queremos insertar la fecha actual al momento de crear un registro, podemos utilizar la función CURRENT_DATE para obtenerla.
Ejercicio
COLUMN
TIPO
A
nombre TEX
T
precio INT
stock INT
fecha DAT
E
Si tenemos la tabla productos, inserta un nuevo producto con los siguientes datos:
nombre: Bolso
stock: 10
fecha: CURRENT_DATE
INSERT INTO productos (nombre, stock, fecha) VALUES ('Bolso', 10, CURRENT_DATE);
Tu resultado
02-03
Bolso 10 2024-
02-03
Si queremos insertar una fecha cualquiera al momento de crear un registro, simplemente debemos hacerlo especificando la fecha en el
formato esperado.
El formato de fecha es: YYYY-MM-DD, o sea año-mes-día, donde el año es de 4 dígitos, el mes es de 2 dígitos y el día es de 2 dígitos.
Ejercicio
nombre TEX
T
precio INT
stock INT
fecha DAT
E
nombre: Bolso
stock: 10
fecha: fecha_con_formato
La fecha del producto debe ser del primero de enero del 2023.
INSERT INTO productos (nombre, stock, fecha) VALUES ('Bolso', 10, '2023-01-01');
Tu resultado
NOMBR PRECI STOC FECH
E O K A
Bolso 10 2023-
01-01
Por ejemplo, si tenemos una tabla llamada ventas con las columnas producto, cantidad y precio, podemos agregar varios registros a la
tabla usando:
INSERT INTO ventas VALUES ('Camiseta', 5, 2000), ('Pantalón', 3, 1500), ('Zapatos', 2, 3000);
Ejercicio
Gorro 5 1000
Camiseta 10 500
Pantalón 8 1500
INSERT INTO ventas VALUES ('Gorro', 5, 1000), ('Camiseta', 10, 500), ('Pantalón', 8, 1500);
Tu resultado
PRODUCT CANTIDA PRECI
O D O
Gorro 5 1000
Camiseta 10 500
Pantalón 8 1500
En una base de datos SQL, es posible agilizar el proceso de inserción de datos en una tabla mediante el uso de un campo
autoincremental. Este tipo de campo es especialmente útil cuando se trata de gestionar identificadores únicos, como por ejemplo el
campo "id" de una tabla. La característica de autoincremento se logra empleando la cláusula AUTOINCREMENT en la definición del
campo.
Para ilustrar este proceso, consideremos una tabla llamada "empleados" con tres columnas: "id" (autoincremental), "nombre" y
"apellido". Esta es la forma en que se crea la tabla:
CREATE TABLE empleados (id INTEGER PRIMARY KEY AUTOINCREMENT, nombre TEXT,apellido TEXT);
Aquí, hemos definido la columna "id" como un campo autoincremental utilizando la cláusula AUTOINCREMENT, lo que asegura que
se generará automáticamente un valor único y creciente para cada nuevo registro.
Supongamos que deseamos insertar un nuevo empleado en esta tabla. Podemos utilizar la siguiente consulta SQL:
Al ejecutar esta consulta, se creará un nuevo empleado en la tabla "empleados". La columna "id" se incrementará automáticamente,
mientras que los valores proporcionados para "nombre" y "apellido" serán almacenados en las columnas correspondientes. Esto
garantiza que cada nuevo empleado tendrá un identificador único y que el proceso de inserción sea más eficiente.
Ejercicio
Dada la tabla empleados con las columnas id, nombre y apellido, crea un nuevo empleado con el nombre "Jane" y el apellido "Smith".
I NOMBR APELLID
D E O
1 Jane Smith
Supongamos que queremos crear una tabla llamada "Productos" con las siguientes columnas:
CREATE TABLE Productos (ID INTEGER PRIMARY KEY AUTOINCREMENT, Nombre TEXT, Precio INTEGER DEFAULT 10);
Si insertamos un nuevo producto sólo con el nombre, se utilizará automáticamente el valor por defecto del precio:
Si deseamos insertar un producto con un precio diferente, simplemente proporcionamos el valor correspondiente:
Ejercicio
Dada la tabla usuarios con las columnas id, nombre, apellido, email y telefono, crea un nuevo usuario con los valores:
nombre: Lucía
apellido: Sánchez
email: luciasanchez@[Link]
INSERT INTO usuarios (Nombre, apellido, email, telefono) VALUES ('Lucía', 'Sánchez',
'luciasanchez@[Link]', '111-1111');
Tu resultado
En SQL, la cláusula DELETE se utiliza para eliminar registros de una tabla. Cuando se ejecuta la instrucción DELETE FROM
nombre_tabla, se eliminan todos los registros de la tabla especificada.
Es importante tener en cuenta que esta operación es irreversible y eliminará permanentemente los datos de la tabla, por lo que debes
tener mucho cuidado al usar esta instrucción.
Ejercicios
Por ejemplo, si tenemos una tabla de productos y queremos eliminar solo aquellos productos cuyo precio sea igual a 1000, podemos
usar la siguiente consulta:
Ejercicio
La sentencia UPDATE se utiliza para realizar modificaciones en datos ya existentes de una tabla.
Supongamos que tenemos una tabla ventas con una columna llamada "total". Si queremos aumentar en un 10% el total de todas las
ventas registradas en la tabla, podemos hacerlo de la siguiente manera:
La instrucción UPDATE afecta todas las filas de la tabla, ya que no hemos utilizado la cláusula WHERE para establecer una condición
de filtro.
Ejercicio
Edita la columna "registrado" para que todos los usuarios tengan el valor TRUE
Si queremos editar solamente algunas filas de nuestra tabla, podemos utilizar UPDATE en conjunto con WHERE. De esta forma solo
se modificarán los registros que cumplan con la condición especificada.
Supongamos que gestionamos una tabla llamada empleados que contiene información sobre los empleados de una empresa. Entre las
columnas se encuentran id_empleado, nombre, salario y departamento. Si deseamos aumentar el salario en un 15% solamente para los
empleados que trabajan en el departamento de "Ventas", podríamos emplear la instrucción UPDATE junto con WHERE de la
siguiente manera:
UPDATE empleados SET salario = salario * 1.15 WHERE departamento = 'Ventas';
Es importante ser precavido al elegir la condición de filtrado para tus filas. De esta manera, te aseguras de no alterar accidentalmente
datos equivocados.
Ejercicio
I
NOMBRE APELLIDO EMAIL TELEFONO
D
En SQL es posible editar múltiples columnas de un registro utilizando la cláusula SET. Para lograrlo, debemos especificar el nombre
de cada columna que queremos modificar, seguido del nuevo valor que queremos asignarle.
UPDATE tabla
SET
columna1 = 'nuevo_valor',
columna2 = 'nuevo_valor',
columna3 = 'nuevo_valor'
WHERE
condicion;
UPDATE usuarios
SET
nombre = 'Juan',
apellido = 'Pérez'
WHERE
id = 1;
También es posible escribir la consulta en una sola línea, pero es recomendable utilizar saltos de línea para mejorar la legibilidad del
código.
Ejercicio
id INTEGE
R
titulo TEXT
contenido TEXT
autor TEXT
fecha TEXT
Edita el post con id 1 para que tenga el título "Aprendiendo SQL" y el contenido "SQL es un lenguaje de programación para gestionar
bases de datos relacionales".
UPDATE posts
SET
titulo = 'Aprendiendo SQL',
contenido = 'SQL es un lenguaje de programación para gestionar bases de datos relacionales'
WHERE
id = 1;
Tu resultado
post 5 01-05
Hasta este punto, hemos aprendido cómo realizar consultas en tablas predefinidas, e incluso cómo insertar datos a las tablas, pero
¿cómo creamos nuestras propias tablas?
Para crear una tabla en SQL, se utiliza la sentencia CREATE TABLE de la siguiente forma:
Esta sentencia permite definir la estructura de la tabla, incluyendo el nombre de las columnas y sus tipos de datos. Veamos un ejemplo
de cómo crear una tabla de productos que incluye diferentes tipos de datos para las columnas:
Luego, una vez creada la tabla, podemos insertar datos tal como aprendimos en ejercicios anteriores:
INSERT INTO productos values ('Ipad Pro 2022'), ('Iphone 13 Pro Max'), ('Macbook Pro 2023');
Ejercicio
Crea una tabla llamada alumnos que almacene una columan nombre de tipo texto
TIPO
COLUMN DE
A DAT
O
nombre texto
nombre: Lucía
Pista: Para poder ingresar las dos queries requeridas, recuerda añadir punto y coma al final de cada una.
CREATE TABLE alumnos (nombre text); INSERT INTO alumnos values ('Lucía');
Tu resultado
NOMBR
E
Lucía
Una tabla con múltiples columnas
Al momento de crear una tabla podemos especificar múltiples columnas, cada una con su nombre y tipo de dato. Por ejemplo, si
queremos crear una tabla de productos que incluya el nombre, descripción y precio de cada producto, podemos hacerlo de la siguiente
forma:
Ejercicio
TIPO
COLUMN DE
A DAT
O
nombre texto
apellido texto
telefono texto
Pista: para poder ingresar las dos queries requeridas, recuerda añadir punto y coma al final de cada una.
CREATE TABLE alumnos (nombre TEXT, apellido TEXT, telefono TEXT); INSERT INTO alumnos (Nombre,
apellido, telefono) VALUES ('Lucía', 'Sánchez', '12345678');
Tu resultado
Adicionalmente a los datos de tipo Texto podemos utilizar otros tipos de datos, en este ejercicio abordaremos los 3 siguientes tipos.
Ejercicio
Crea una tabla llamada usuarios con las siguientes columnas:
TIPO
COLUMN
DE
A
DATO
nombre text
apellido text
edad integer
activo boolean
nacimiento date
Luego inserta un registro dentro de la tabla creada utilizado los siguientes datos:
nombre: Lucía
apellido: Sánchez
edad: 25
activo: true
nacimiento: 1996-01-01
Pista: para poder ingresar las dos queries requeridas, recuerda añadir punto y coma al final de cada una.
CREATE TABLE usuarios (nombre TEXT, apellido TEXT, edad integer, activo boolean, nacimiento date);
INSERT INTO usuarios (Nombre, apellido, edad, activo, nacimiento) VALUES ('Lucía', 'Sánchez',
'25', '1', '1996-01-01');
Tu resultado
Tipos reales
En este ejercicio veremos el tipo de dato REAL, que permite almacenar números con decimales.
Ejercicio
temperatura_celsius real
TEMPERATURA_CELS
IUS
23.4
26.5
27.1
Importante. Para ingresar la parte decimal de los números, utiliza el punto (.) como separador decimal
23.4
26.5
27.1
Borrar un tabla
En SQL podemos utilizar el comando DROP TABLE para eliminar una tabla.
Por ejemplo, si queremos eliminar la tabla temperaturas que creamos en el ejercicio anterior, podemos hacerlo con la siguiente query:
Ejercicio
En este ejercicio tendremos una tabla con datos que no nos interesan, deberemos borrarla, crearla de nuevo y poblarla con los datos
pedidos.
ciudad TEXT
temperatura REAL
fecha Date
01-01
Importante: para poder ingresar las queries requeridas, recuerda añadir punto y coma al final de cada una.
DROP TABLE temperaturas; create table temperaturas (ciudad text, temperatura real, fecha date);
INSERT INTO temperaturas (ciudad, temperatura, fecha) VALUES ('Buenos Aires', '20', '2024-01-01');
INSERT INTO temperaturas (ciudad, temperatura, fecha) VALUES ('Buenos Aires', '21', '2024-01-02');
INSERT INTO temperaturas (ciudad, temperatura, fecha) VALUES ('Santiago', '22', '2024-01-01');
INSERT INTO temperaturas (ciudad, temperatura, fecha) VALUES ('Santiago', '23', '2024-01-02');
Tu resultado
CIUDA TEMPERATUR
FECHA
D A
Buenos 20 2024-01-01
Aires
Buenos 21 2024-01-02
Aires
Santiago 22 2024-01-01
Santiago 23 2024-01-02
En este ejercicio aprenderemos a añadir una columna a una tabla existente. Para ello, utilizaremos la sentencia ALTER TABLE, que nos
permite modificar la definición de una tabla.
donde tenemos que especificar el nombre de la tabla existente, el nombre de la columna nueva y el tipo de dato que utilizaremos.
Por ejemplo si tenemos la tabla personas con las columnas nombre y apellido, y queremos agregar la columna edad de tipo INTEGER,
podemos hacerlo de la siguiente manera:
Ejercicio
En este ejercicio, vamos a modificar la tabla productos para agregar la columna descripcion de tipo TEXT.
TIPO
COLUMN DE
A DAT
O
nombre TEXT
precio REAL
Importante: para poder ingresar las queries requeridas, recuerda añadir punto y coma al final de cada una.
INSERT INTO
productos (nombre, precio, descripcion)
VALUES
('Camisa', 1000.00, 'Camisa de manga corta'),
('Pantalón', 2000.00, 'Pantalón de mezclilla'),
('Camisa XL', 1000.00, 'Camisa de manga larga');
Tu resultado
NOMBR PRECI DESCRIPCIO
E O N
Valor 500
Antiguo
Introducción a restricciones
Al crear tablas, podemos añadir restricciones (En inglés constraints) a las columnas para evitar que se ingresen datos que no cumplan
ciertas condiciones.
En este ejercicio, aprenderemos a usar la restricción NOT NULL, que impide valores nulos en una columna. Por ejemplo, al crear una
tabla de personas con nombre y apellido, podemos hacer que el nombre sea obligatorio (no nulo) y el apellido opcional.
Para lograrlo crearemos la tabla de la siguiente forma:
Para agregar una restricción simplemente debemos especificarla junto con la columna.
Para indicar las restricciones utilizaremos una columna adicional llamada Constraints en nuestros diagramas. Ejemplo con la
tabla personas:
DAT
COLUM A CONSTRAIN
N TYP TS
E
apellido TEXT
Pongamos a prueba nuestra restricción con distintas consultas y observemos los resultados.
QUERY RESULTADO
INSERT Funciona
INTO
personas
(nombre,
apellido)
VALUES
('Juan',
'Pérez');
INSERT No funciona,
INTO error: NOT
personas NULL constraint
(nombre, failed:
apellido) [Link]
VALUES
(NULL,
'Pérez');
INSERT No funciona,
QUERY RESULTADO
(apellido) failed:
VALUES [Link]
('Pérez');
En resumen: En esta tabla que acabamos de crear podremos hacer un insert de una persona con nombre y sin apellido
pero no podremos ingresar una persona sin nombre.
Ejercicio
Crea una nueva tabla llamada empleados con las siguientes columnas:
TIPO
COLUMN DE RESTRICCION
A DAT ES
O
apellido TEXT
nombre: Pedro
apellido: Pérez
NOMBR APELLID
E O
Pedro Pérez
personas
TIPO
COLUMN DE RESTRICCION
A DAT ES
O
nombre TEXT
apellido TEXT
y queremos agregarle la restricción NOT NULL a la columna nombre. El problema es que en SQLite no podemos agregar
restricciones directamente a una tabla existente.
En otros motores de bases de datos como PostgreSQL o MySQL si es posible agregar restricciones a tablas existentes.
2.
TIPO
COLUMN DE RESTRICCION
A DAT ES
O
patente TEXT
PATENT
E
ABC123
ABC124
En SQLite borrar una restricción tiene las mismas limitaciones que modificarla y el procedimiento es similar.
Para el ejemplo tendremos una tabla llamada temperaturas con la siguiente estructura:
TIPO
DE RESTRICCION
COLUMNA
DAT ES
O
1.
Ejercicio
TIPO
COLUMN RESTRICCION
DE
A ES
DATO
edad INTEGE
R
SQL
CREATE
TABLE
"personas"
( nombre
TEXT,
SQL
apellido
TEXT,
edad
INTEGER
)
Restricción unique
La restricción de unicidad, o UNIQUE, nos permite evitar duplicados en una columna específica. Un caso muy popular de esta
restricción es evitar personas con el mismo correo electrónico.
Para agregar una restricción de UNIQUE simplemente tenemos que especificar el constraint justo después de especificar el tipo de
dato. Por ejemplo:
Pongamos a prueba nuestra restricción con distintas consultas y observemos los resultados.
QUERY FUNCIONA
'[Link]@[Link]');
'[Link]@[Link]'); failed:
[Link]
'[Link]@[Link]');
En resumen: En esta tabla que acabamos de crear, el correo electrónico de cada persona debe ser único; no podremos ingresar dos
personas con el mismo correo electrónico.
Ejercicio
En este ejercicio, vamos a crear una tabla llamada productos con las siguientes columnas:
TIPO
COLUMN DE RESTRICCION
A DAT ES
O
Pista: para poder ingresar las dos queries requeridas, recuerda añadir punto y coma al final de cada una.
Si quieres probar un insert para observar el error puedes hacerlo con el código CAM-001.
create table "productos" (nombre text, precio real, codigo text unique);
insert into productos (nombre, precio, codigo) values ('Camisa', 1000, 'CAM-001');
insert into productos (nombre, precio, codigo) values ('Pantalón', 2000, 'PAN-001');
insert into productos (nombre, precio, codigo) values ('Camisa XL', 1000, 'CAM-002');
Tu resultado
NOMBR PRECI CODIG
E O O
Not Null, que permite especificar que un valor no puede ser nulo.
Unique, que permite especificar que un valor debe ser único.
En este ejercicio aprenderemos a utilizar la restricción CHECK, que nos permite establecer una condición que los valores de una
columna deben cumplir.
Para agregar una restricción de CHECK simplemente tenemos que especificarlo en la definición de la columna, proporcionando la
condición que debe cumplir el valor de la columna. Por ejemplo:
CREATE TABLE empleados (
nombre TEXT,
salario REAL CHECK (salario > 0)
);
FUNCION
QUERY
A
INSERT Funciona
INTO
empleados
(nombre,
salario)
VALUES
('Juan',
3000);
INSERT No funciona,
INTO error: CHEC
empleados K constraint
(nombre, failed:
salario) empleados
FUNCION
QUERY
A
VALUES
('Ana', -
3000);
INSERT Funciona
INTO
empleados
(nombre,
salario)
VALUES
('Luis',
3000);
Ejercicio
En este ejercicio, vamos a crear una tabla llamada productos con las siguientes columnas:
TIPO
COLUMN RESTRICCION
DE
A ES
DATO
Camisa 1000.00 10
Pantalón 2000.00 5
Camisa 1000.00 3
XL
Pista: para poder ingresar las dos queries requeridas, recuerda añadir punto y coma al final de cada una.
Si quieres probar un insert para observar el error puedes hacerlo ingresando un stock negativo.
create table "productos" (nombre text, precio real, stock integer check (stock >= 0));
insert into productos (nombre, precio, stock) values ('Camisa', 1000, '10');
insert into productos (nombre, precio, stock) values ('Pantalón', 2000, '5');
insert into productos (nombre, precio, stock) values ('Camisa XL', 1000, '3');
Tu resultado
Camisa 1000 10
Pantalón 2000 5
Camisa 1000 3
XL
Clave unica
La clave primaria, o en inglés PRIMARY KEY nos ayuda a identificar de forma única cada registro en una tabla. Esto lo hace
impidiendo que se ingresen valores duplicados o nulos en la columna que es clave primaria.
MONT
FECHA
O DE
I DE
LA
D EMISIO
BOLET
N
A
1 10.000 2021-10-
01
2 12.000 2021-10-
02
3 16.000 2021-10-
03
Si dijeramos que el campo id es la clave primaria, entonces cada registro de la tabla tiene un valor único para el campo id. Este id no
podría ser nulo, ni podría ser el mismo que el de otro registro.
Cuando tenemos una clave primaria, tenemos certeza de que podemos buscar cualquier registro en la base de datos y luego modificarlo
o eliminarlo, y no habrá ningún otro registro modificado o eliminado que el seleccionado. Esto nos permite cuidar la integridad de los
datos.
Ejercicio
DAT
COLUM
A CONSTRAIN
N
TYP TS
NAME
E
id INT PRIMARY
KEY
title TEXT
content TEXT
inserta los siguientes registros:
I
TITLE CONTENT
D
1 Introducción ¡Bienvenido al
mundo de la
programación!
2 Primeros Sumérgete en
Pasos los conceptos
básicos de la
programación.
3 Temas Explora
Avanzados conceptos y
técnicas
avanzadas en
programación.
Pista: para poder ingresar las dos queries requeridas, recuerda añadir punto y coma al final de cada una.
Si quieres poner a prueba la clave primaria puedes intentar insertar un id nulo o un id que ya hayas ingresado.
CREATE TABLE posts (id INT PRIMARY KEY, title text, content text);
insert into posts (id, title, content) values (1, 'Introducción', '¡Bienvenido al mundo de la
programación!');
insert into posts (id, title, content) values (2, 'Primeros Pasos', 'Sumérgete en los conceptos
básicos de la programación.');
insert into posts (id, title, content) values (3, 'Temas Avanzados', 'Explora conceptos y técnicas
avanzadas en programación.');
Tu resultado
I
TITLE CONTENT
D
1 Introducción ¡Bienvenido al
mundo de la
programación!
2 Primeros Sumérgete en
Pasos los conceptos
básicos de la
programación.
I
TITLE CONTENT
D
3 Temas Explora
Avanzados conceptos y
técnicas
avanzadas en
programación.
Autoincremental
Los campos autoincrementales nos permiten generar un valor único de forma automática para cada registro que insertemos en una
tabla.
1 10.000 2021-10-
01
2 12.000 2021-10-
02
3 16.000 2021-10-
03
Podemos ingresar un nuevo registro sin tener que especificar el valor del campo id, y la base de datos se encargará de generar un valor
único para ese campo. Para lograrlo simplemente no incluimos el campo id en la query.
Ejemplo:
MONT
FECHA
O DE
I DE
LA
D EMISIO
BOLET
N
A
1 10.000 2021-10-
01
2 12.000 2021-10-
02
3 16.000 2021-10-
03
4 20.000 2021-10-
04
Un campo definido como INTEGER (o INT) + PRIMARY KEY se convierte automáticamente en un campo autoincremental en
SQLITE
Ejercicio
TIPO
RESTRICCION
COLUMNA DE
ES
DATO
fecha_creacion DATE
Ana 2024-01-01
Gonzalo 2024-01-02
Juan 2024-01-03
María 2024-01-04
CREATE TABLE usuarios (id INT PRIMARY KEY, nombre text not null, fecha_creacion date);
insert into usuarios (id, nombre, fecha_creacion) values (1, 'Ana', '2024-01-01');
insert into usuarios (id, nombre, fecha_creacion) values (2, 'Gonzalo', '2024-01-02');
insert into usuarios (id, nombre, fecha_creacion) values (3, 'Juan', '2024-01-03');
insert into usuarios (id, nombre, fecha_creacion) values (4, 'María', '2024-01-04');
Tu resultado
I NOMBR FECHA_CREACI
D E ON
1 Ana 2024-01-01
2 Gonzalo 2024-01-02
3 Juan 2024-01-03
4 María 2024-01-04
Autoincremental parte 2
Cuando tenemos campos autoincrementales en una tabla e insertamos un nuevo registro con un valor mas alto que el de la secuencia
actual, la base de datos se encarga de actualizar la secuencia para que el siguiente registro tenga un valor mayor al del registro que
acabamos de insertar.
I NOMBR
D E
1 Ana
I NOMBR
D E
2 Gonzalo
3 Juan
I NOMBR
D E
1 Ana
2 Gonzalo
3 Juan
I NOMBR
D E
10 María
11 Pedro
Ejercicio
TIPO
COLUMN RESTRICCION
DE
A ES
DATO
fecha DATE
1000.00 2024-
01-01
2000.00 2024-
01-02
3000.00 2024-
01-03
10 4000.00 2024-
01-04
5000.00 2024-
01-05
Importante: Al único campo que vamos a agregar un id de forma personalizada va a ser al cuarto registro, esto con el fin de observar
la relación que se genera entre el campo incremental y como aumenta según el valor que insertemos.
CREATE TABLE transacciones (id INT PRIMARY KEY, monto real not null, fecha date);
insert into transacciones (id, monto, fecha) values (1, 1000, '2024-01-01');
insert into transacciones (id, monto, fecha) values (2, 2000, '2024-01-02');
insert into transacciones (id, monto, fecha) values (3, 3000, '2024-01-03');
insert into transacciones (id, monto, fecha) values (10, 4000, '2024-01-04');
insert into transacciones (id, monto, fecha) values (11, 5000, '2024-01-05');
Tu resultado
I MONT FECH
D O A
1 1000 2024-
01-01
2 2000 2024-
01-02
3 3000 2024-
01-03
10 4000 2024-
01-04
11 5000 2024-
I MONT FECH
D O A
01-05
La clave primaria no está limitada exclusivamente a valores numéricos; también se pueden utilizar datos de texto. Tomemos, por
ejemplo, una tabla de personas, donde podríamos emplear la dirección de correo electrónico como clave primaria, ya que cada
individuo posee una dirección de correo única.
En SQLite, los campos que son de tipo INTEGER y se designan como PRIMARY KEY no pueden contener valores nulos. No
obstante, a diferencia de otros sistemas de gestión de bases de datos como MySQL o PostgreSQL, cuando se utiliza PRIMARY KEY
con tipos de datos como texto u otros, se permite que el valor sea nulo.
Por lo tanto, si queremos que un campo sea tanto clave primaria como no nulo, debemos especificarlo mediante la combinación de
PRIMARY KEY y NOT NULL.
Ejemplo:
DAT
COLUM
A CONSTRAIN
N
TYP TS
NAME
E
T KEY NOT
NULL
nombre TEX
apellido TEX
Puedes probar usando el mismo email en dos registros diferentes para que observes como se comporta la restricción.
CREATE TABLE personas (email text PRIMARY KEY NOT NULL, nombre text, apellido text);
insert into personas (email, nombre, apellido) values ('example1@[Link]', 'John', 'Doe' );
insert into personas (email, nombre, apellido) values ('example2@[Link]', 'Jane', 'Smith' );
insert into personas (email, nombre, apellido) values ('example3@[Link]', 'Mike', 'Johnson'
);
Tu resultado
NOMBR APELLID
EMAIL
E O
Múltiples tablas
Cuando trabajamos con bases de datos relacionales, surge con frecuencia la necesidad de combinar datos de varias tablas.
Veamos un ejemplo:
Tabla usuarios
NOMBR EDA
EMAIL1
E D
[Link]@[Link] Juan 30
Pérez
NOMBR EDA
EMAIL1
E D
[Link]@[Link] Maria 25
González
Tabla datos_contacto
TELÉFON
EMAIL2
O
[Link]@[Link] 555-123-
4567
[Link]@[Link] 444-987-
6543
TELÉFON
EMAIL2
O
[Link]@[Link] 777-555-
8888
[Link]@[Link] 111-222-
3333
[Link]@[Link] 999-888-
7777
[Link]@[Link] 333-111-
0000
Si nos pidieran obtener todos los email, nombre edad y teléfono de todos los usuarios tendríamos que unir estas tablas. Para esto existe
la claúsula JOIN.
En nuestro ejemplo, podemos unir las tablas con la siguiente consulta: SELECT * FROM usuarios JOIN datos_contacto ON email1 = email2
Para unir tablas tenemos que establecer un punto de unión. En este caso lo que tienen en común ambas tablas es el email.
Ejercicio
Utilizando lo aprendido selecciona todos los usuarios junto a sus notas. Observa los resultados antes de avanzar.
tabla usuarios
NOMBR EDA
EMAIL1
E D
[Link]@[Link] Juan 30
Pérez
[Link]@[Link] Maria 25
González
tabla notas
NOTA
EMAIL2
S
[Link]@[Link] 90
[Link]@[Link] 100
[Link]@[Link] 80
[Link]@[Link] 0
[Link]@[Link] 100
[Link]@[Link] 100
Tu resultado
NOMBR EDA NOTA
EMAIL1 EMAIL2
E D S
En el ejercicio anterior teníamos los atributos email1 y email2. En este ejercicio aprenderemos que es posible que dos atributos
distintos compartan el mismo nombre, siempre y cuando estén ubicados en diferentes tablas.
Para ejemplificar esto utilizaremos el nombre email en ambas tablas.
Tabla usuarios
NOMBR EDA
EMAIL
E D
[Link]@[Link] Juan 30
Pérez
[Link]@[Link] Maria 25
González
Tabla datos_contacto
TELÉFON
EMAIL
O
[Link]@[Link] 555-123-
4567
[Link]@[Link] 444-987-
6543
[Link]@[Link] 777-555-
8888
[Link]@[Link] 111-222-
3333
[Link]@[Link] 999-888-
7777
[Link]@[Link] 333-111-
0000
Uniremos los datos de ambas tablas utilizando JOIN, pero en esta ocasión, cuando especifiquemos el punto de unión, utilizaremos el
nombre de la tabla junto con el del atributo:
Al hacerlo de esta forma, SQL puede entender a cual email nos referimos en cada situación.
Ejercicio
Utilizando lo aprendido, selecciona todos los usuarios junto a sus notas. Recuerda que para especificar la clave de unión debes utilizar
el nombre de la tabla para evitar ambiguedad. Observa los resultados antes de avanzar.
Tabla usuarios
NOMBR EDA
EMAIL
E D
[Link]@[Link] Juan 30
Pérez
[Link]@[Link] Maria 25
NOMBR EDA
EMAIL
E D
González
Tabla notas
NOTA
EMAIL
S
[Link]@[Link] 90
[Link]@[Link] 100
[Link]@[Link] 80
[Link]@[Link] 0
NOTA
EMAIL
S
[Link]@[Link] 100
[Link]@[Link] 100
Tabla usuarios
NOMBR EDA
EMAIL
E D
[Link]@[Link] Juan 30
Pérez
[Link]@[Link] Maria 25
González
Tabla datos_contacto
TELÉFON
EMAIL
O
[Link]@[Link] 555-123-
4567
[Link]@[Link] 444-987-
6543
TELÉFON
EMAIL
O
[Link]@[Link] 777-555-
8888
[Link]@[Link] 111-222-
3333
[Link]@[Link] 999-888-
7777
[Link]@[Link] 333-111-
0000
puede ser que al seleccionar los datos no deseemos mostrar los emails dos veces. Para esto, en lugar de utilizar SELECT * utilizaremos
De esta forma seleccionamos todo lo de la tabla usuarios y sólo los teléfonos de la tabla datos_contacto.
Ejercicio
Dada las siguientes tablas:
usuarios
NOMBR EDA
EMAIL
E D
[Link]@[Link] Juan 30
Pérez
[Link]@[Link] Maria 25
González
notas
NOTA
EMAIL
S
[Link]@[Link] 90
NOTA
EMAIL
S
[Link]@[Link] 100
[Link]@[Link] 80
[Link]@[Link] 0
[Link]@[Link] 100
[Link]@[Link] 100
Selecciona de la tabla usuarios el email, nombre y edad y de la tabla notas sólo las notas. Une los registros de ambas tablas utilizando
el email.
[Link]@[Link] Juan 30 90
NOMBR EDA NOTA
EMAIL
E D S
Pérez
¿Qué sucedería si los emails presentes en una tabla no se encuentran en la otra tabla al momento de unir los datos?
tabla usuarios
NOMBR EDA
EMAIL
E D
[Link]@[Link] Juan 30
Pérez
[Link]@[Link] Maria 25
González
tabla datos_contacto
TELÉFON
EMAIL
O
[Link]@[Link] 555-123-
4567
[Link]@[Link] 444-987-
6543
TELÉFON
EMAIL
O
[Link]@[Link] 777-555-
8888
La respuesta es bien sencilla: si no hay ningún dato común entre ambas tablas, no obtendremos resultados.
Utilizando lo aprendido previamente, selecciona todos los registros de la unión de las tablas usuarios y datos_contacto. Observa el
resultado.
Cuando queremos utilizar joins con las otras claúsulas que hemos aprendido, tenemos que considerar el orden de estas.
COMAND SE LEE
O COMO:
SELECT Selecciona
COMAND SE LEE
O COMO:
estos datos.
FROM De esta
tabla.
esta tabla.
valores que
cumplan tal
condición.
resultados
por este
criterio.
COMAND SE LEE
O COMO:
estos
criterios
agrupados.
resultados
por este
otro
criterio.
resultados
a esta
cantidad.
Ejercicio
Dadas las siguientes tablas, selecciona toda la información del usuario [Link]@[Link]
Tabla usuarios
NOMBR EDA
EMAIL
E D
[Link]@[Link] Juan 30
Pérez
[Link]@[Link] Maria 25
González
Tabla notas
NOTA
EMAIL
S
[Link]@[Link] 90
[Link]@[Link] 100
[Link]@[Link] 80
[Link]@[Link] 0
[Link]@[Link] 100
[Link]@[Link] 100
Pista: debes seleccionar todo, unir las tablas y filtrar por el email respectivo.
Inner Join
En SQL existen varias forma de unir tablas. Cuando no se especifica el tipo de join se utiliza INNER JOIN, es decir,
es lo mismo que
En una operación de Inner Join se combinan los registros de ambas tablas siempre y cuando la clave en común esté en ambas tablas. Si
en una de las tablas no está la clave ese registro no aparecerá en el resutlado final.
Ejercicio
Une las tablas utilizando JOIN (o INNER JOIN) para obtener todos los registros de ambas tablas. Mira las tablas antes de realizar el
ejercicio y pon especial atención en Francisco quien no tiene ninguna nota en el sistema.
Tabla usuarios
NOMBR EDA
EMAIL
E D
[Link]@[Link] Juan 30
Pérez
[Link]@[Link] Maria 25
González
Tabla notas
NOTA
EMAIL
S
[Link]@[Link] 90
[Link]@[Link] 100
[Link]@[Link] 80
[Link]@[Link] 100
[Link]@[Link] 100
Left Join
Con los siguientes datos, al hacer un INNER JOIN no obtendremos dentro de los resultados a Franscisco, lo cual podría ser un gran
error si estuvieramos haciendo un reporte de todos los estudiantes.
Tabla usuarios
NOMBR EDA
EMAIL
E D
[Link]@[Link] Juan 30
Pérez
[Link]@[Link] Maria 25
González
Tabla notas
NOTA
EMAIL
S
[Link]@[Link] 90
NOTA
EMAIL
S
[Link]@[Link] 100
[Link]@[Link] 80
[Link]@[Link] 100
[Link]@[Link] 100
Existe un tipo especial de JOIN que nos puede traer todos los usuarios junto a sus notas. Con LEFT JOIN podemos obtener todos los
registros de los datos de usuarios y sus correspondientes notas, incluso si algunos usuarios no tienen notas asociadas.
En un LEFT JOIN, todas las filas de la tabla izquierda (en este caso, la tabla de usuarios) aparecerán en el resultado, y si un usuario no
tiene una coincidencia en la tabla derecha (la tabla de notas), los campos correspondientes en la tabla de notas se llenarán con valores
NULL.
La Sintaxis para utilizar LEFT JOIN es similar a INNER JOIN. SELECT * FROM tabla1 LEFT JOIN tabla2 ON [Link] = [Link]
Ejercicio
Se tiene una tabla de empleados y otra de departamentos. Utilizando lo aprendido selecciona a todos los empleados junto a sus
departamentos correspondientes, incluyendo a los empleados que aún no han sido asignados a ningún departamento. En ambas tablas
existe la columna email.
Left Join
Con los siguientes datos, al hacer un INNER JOIN no obtendremos dentro de los resultados a Franscisco, lo cual podría ser un gran
error si estuvieramos haciendo un reporte de todos los estudiantes.
Tabla usuarios
NOMBR EDA
EMAIL
E D
[Link]@[Link] Juan 30
Pérez
[Link]@[Link] Maria 25
González
Tabla notas
NOTA
EMAIL
S
[Link]@[Link] 90
[Link]@[Link] 100
[Link]@[Link] 80
[Link]@[Link] 100
[Link]@[Link] 100
Existe un tipo especial de JOIN que nos puede traer todos los usuarios junto a sus notas. Con LEFT JOIN podemos obtener todos los
registros de los datos de usuarios y sus correspondientes notas, incluso si algunos usuarios no tienen notas asociadas.
En un LEFT JOIN, todas las filas de la tabla izquierda (en este caso, la tabla de usuarios) aparecerán en el resultado, y si un usuario no
tiene una coincidencia en la tabla derecha (la tabla de notas), los campos correspondientes en la tabla de notas se llenarán con valores
NULL.
La Sintaxis para utilizar LEFT JOIN es similar a INNER JOIN. SELECT * FROM tabla1 LEFT JOIN tabla2 ON [Link] = [Link]
Ejercicio
Se tiene una tabla de empleados y otra de departamentos. Utilizando lo aprendido selecciona a todos los empleados junto a sus
departamentos correspondientes, incluyendo a los empleados que aún no han sido asignados a ningún departamento. En ambas tablas
existe la columna email.
Pérez
Right Join
Mientras que el LEFT JOIN devuelve todas las filas de la tabla izquierda y las coincidencias correspondientes de la tabla derecha
(rellenando con NULL si no hay coincidencia), el RIGHT JOIN hace lo contrario: devuelve todas las filas de la tabla derecha y las
coincidencias correspondientes de la tabla izquierda.
Utilizando las tablas previas de "usuarios" y "notas", si quieres obtener todos los registros de las notas y los correspondientes usuarios,
incluso si hay notas que no tienen usuarios asociados (lo cual sería atípico en este contexto, pero sirve para el ejemplo), puedes utilizar
RIGHT JOIN:
Tabla usuarios
NOMBR EDA
EMAIL
E D
[Link]@[Link] Juan 30
Pérez
[Link]@[Link] Maria 25
González
Tabla notas
NOTA
EMAIL
S
[Link]@[Link] 90
[Link]@[Link] 100
[Link]@[Link] 100
[Link]@[Link] 100
emilio@[Link] 90
En este ejemplo puntual emilio@[Link] tiene notas pero no tenemos su registro en la tabla de usuarios. Utilizando RIGHT JOIN
podemos mostrar su información.
Ejercicio
Dadas las tablas empleados y departamentos, se pide todos los registros de los departamentos de una oficina y sus correspondientes
empleados, incluso si hay departamentos sin empleados asociados. En ambas tablas existe la columna email.
SELECT * FROM empleados RIGHT JOIN departamentos ON [Link] = [Link]
Tu resultado
Finanzas
[Link]@[Link] TI
Utilizar LEFT JOIN o RIGHT JOIN depende simplemente de que tabla quieres nombrar primero.
SELECT *
FROM tabla1
LEFT JOIN tabla2 ON [Link] = [Link]
LEFT JOIN y RIGHT JOIN son un reflejo el uno del otro. Sin embargo, existe una pequeña diferencia cuando los utilizamos en
conjunto con SELECT *, dado que los atributos de los primera tabla se mostrarán primero.
Tabla usuarios
NOMBR EDA
EMAIL
E D
[Link]@[Link] Juan 30
Pérez
[Link]@[Link] Maria 25
González
Tabla notas
NOTA
EMAIL
S
[Link]@[Link] 90
[Link]@[Link] 100
[Link]@[Link] 100
[Link]@[Link] 100
emilio@[Link] 90
Con SELECT * FROM usuarios left join notas on [Link] = [Link]; obtendríamos lo siguiente:
Pérez
NOMBR EDA NOTA
EMAIL EMAIL
E D S
Pérez
González
González
En cambio, con SELECT * FROM Notas RIGHT JOIN Usuarios ON [Link] = [Link]; obtendríamos:
Pérez
Pérez
González
González
Para obtener los resultados en el mismo orden simplemente podemos especificar el orden que queremos.
Ejercicio
Selecciona todos los registros de todos los productos (tabla productos) junto a sus precios (tabla precios), incluyendo a los productos
que no tienen precio asignado. Las tablas se relacionan entre si por la columna producto_id.
1 Producto 1 1 10.99
A
2 Producto 2 2 15.99
B
3 Producto
PRODUCTO_I NOMBR PRECIO_I PRODUCTO_I PRECI
D E D D O
Al igual que en las consultas sobre una tabla, podemos utilizar funciones de agregación y agrupado en consultas sobre múltiples tablas.
Supongamos que tenemos dos tablas: una tabla llamada Clientes que almacena información sobre los clientes y otra tabla llamada
Pedidos que almacena información sobre los pedidos realizados por esos clientes. Queremos realizar una consulta que nos muestre la
cantidad total de pedidos realizados por cada cliente. Para esto, ejecutaremos una consulta que utilice la cláusula GROUP BY para
agrupar los pedidos por cliente y contaremos la cantidad total de pedidos para cada cliente.
Ejercicio
Tenemos dos tablas: Productos y Ventas. Realiza una consulta que nos muestre el producto más vendido y la cantidad total de
unidades vendidas de ese producto. La columna que muestre el total de unidades vendidas debe llamarse "total_vendido"
Producto 10 1
A
Producto 15 2
B
Producto 20 3
C
Tabla Ventas
20 '2023-09-01' 1
15 '2023-09-02' 1
CANTIDA FECHAVEN PRODUCTOI
D TA D
10 '2023-09-03' 2
25 '2023-09-04' 3
30 '2023-09-05' 3
SELECT
[Link] AS nombre,
SUM([Link]) AS total_vendido
FROM
Productos p
JOIN Ventas v ON [Link] = [Link]
GROUP BY
[Link]
ORDER BY
Tu resultado
NOMBR TOTAL_VENDI
E DO
Producto 55
C
Clave Foránea
La clave foránea es una restricción que se le puede agregar a una columna de una tabla para indicar que los valores que se inserten en
esa columna deben existir en otra tabla.
Por ejemplo, si tenemos una tabla de personas y una tabla de autos, podríamos agregar una columna persona_id a la tabla de autos, y
agregarle la restricción de clave foránea para indicar que el valor de esa columna debe existir en la tabla de personas. De esta forma
nos aseguramos que no se inserten autos de personas que no existen o que se borren personas que tienen autos asignado a su nombre
dejando autos sin dueño.
personas
TIPO
COLUMN RESTRICCION
DE
A ES
DATO
nombre TEXT
apellido TEXT
autos
TIPO
COLUMN RESTRICCION
DE
A ES
DATO
patente TEXT
R (persona_id)
REFERENCES
personas(id)
personas
I NOMBR APELLID
D E O
1 John Doe
2 Jane Smith
autos
I PATENT PERSONA_I
D E D
1 ABC123 1
2 DEF456 2
Podemos ver que el auto con patente ABC123 pertenece a la persona con id 1, y el auto con patente DEF456 pertenece a la persona
con id 2. Adicionalmente la clave foránea nos asegura que no podamos borrar la persona con id 1 mientras exista un auto con
persona_id 1. De la misma forma, no podremos insertar un auto con persona_id 3, ya que no existe una persona con id 3.
Para agregar una clave foránea a una tabla existente, debemos especificar la restricción FOREIGN KEY seguida del nombre de la
columna y la tabla a la que hace referencia, y finalmente la columna de la tabla a la que hace referencia.
La sintaxis es la siguiente:
Ejercicio
articulos
TIPO
COLUMN RESTRICCION
DE
A ES
DATO
nombre TEXT
precio REAL
categorias
TIPO
COLUMN RESTRICCION
DE
A ES
DATO
nombre TEXT
Se pide agregar una clave foránea a la tabla articulos para que la columna categoria_id haga referencia a la columna id de la
tabla categorias.
Los conceptos de clave primaria y clave foránea son fundamentales para el diseño de bases de datos y los ocuparemos tan
frecuentemente que los abreviare como PK Primary Key y FK Foreign Key respectivamente.
Con la clave primaria podemos identificar de forma única cada registro de una tabla, y con la clave foránea podemos relacionar dos
tablas entre si y evitar que existan registros que no tengan una relación válida.
PK = Primary Key
FK = Foreign Key
A partir de ahora utilizaremos frecuentemente estas abreviaciones. También veremos que casi todas las tablas tendrán una clave
primaria (PK). Esto se debe a que la clave primaria nos ayuda a mantener la integridad de los datos, y nos permite identificar
de forma única cada registro de una tabla.
Una práctica común en el diseño de bases de datos es utilizar una columna llamada id como clave primaria. Esta columna es de
tipo INTEGER y tiene la restricción PRIMARY KEY. Además, es común que esta columna sea autoincremental, es decir, que el
valor de la columna se incremente automáticamente cada vez que se inserta un nuevo registro. Pero esto no es una obligación. Definir
una clave primaria es una decisión de diseño, y en algunos casos puede ser más conveniente utilizar otra columna como clave primaria.
Ejercicio
transacciones
TIPO
COLUMN RESTRICCION
DE
A ES
DATO
monto REAL
usuarios
TIPO
COLUMN RESTRICCION
DE
A ES
DATO
nombre TEXT
apellido TEXT
transacciones
I MONT USUARIO_I
D O D
1 100 1
2 200 2
3 300 1
usuarios
I NOMBR APELLID
D E O
1 John Doe
2 Jane Smith
1. En este ejercicio primero intentaremos crear una transacción con un usuario que no existe para observar el error.
2. Intentaremos borrar un usuario que tiene transacciones asociadas para observar el error.
3. Luego eliminaremos nuestras consultas anteriores y modificaremos la tabla de transacciones para eliminar la clave foránea.
Solo se debe eliminar la clave foránea, no la columna.
TIP: Esto requiere crear una tabla temporal, copiar los datos de la tabla original a la tabla temporal, borrar la tabla original, y
renombrar la tabla temporal con el nombre de la tabla original.
4. Finalmente se deben asociar las transacciones al usuario con id 3. El cual no existe y la idea es demostrar que sin la FK
podemos insertar transacciones sin usuarios asociados.
Los puntos 1 y 2 son para observar que sucede. Para lograr la respuesta correcta tienes que realizar los puntos 3 y 4 en el editor.
monto REAL,
-- Paso 4: Copiar los datos de vuelta a la tabla transacciones desde la tabla temporal