Introducción a relaciones y JOINs (15 minutos)
Explicación:
En bases de datos relacionales, las tablas se conectan mediante claves primarias y claves foráneas (vistos en Lección 1 del Módulo 5). Los JOINs permiten consultar datos de varias tablas basándose en estas relaciones.
Conceptos clave:
- Relaciones:
- Uno a muchos (1:N): Un registro en una tabla se relaciona con varios en otra.
- Ejemplo: Un usuario tiene muchos posts (usuarios.id → posts.id_usuario).
- Muchos a muchos (N:N): Múltiples registros en una tabla se relacionan con múltiples registros en otra, usando una tabla intermedia.
- Ejemplo: Estudiantes y cursos, con una tabla estudiantes_cursos.
- Uno a muchos (1:N): Un registro en una tabla se relaciona con varios en otra.
- JOINs: Operaciones SQL para combinar tablas. Tipos principales:
- INNER JOIN: Devuelve solo los registros que coinciden en ambas tablas.
- Ejemplo: Usuarios con posts (excluye usuarios sin posts).
- LEFT JOIN: Devuelve todos los registros de la tabla izquierda y los coincidentes de la derecha (si no hay coincidencia, devuelve NULL).
- Ejemplo: Todos los usuarios, con o sin posts.
- INNER JOIN: Devuelve solo los registros que coinciden en ambas tablas.
- Sintaxis básica:
SELECT columnas FROM tabla1 [INNER|LEFT] JOIN tabla2 ON tabla1.columna = tabla2.columna;
Por qué es importante:
- Los JOINs permiten consultas complejas, como mostrar productos con sus categorías o usuarios con sus publicaciones.
- En Laravel, Eloquent usa relaciones (hasMany, belongsTo), pero JOINs son esenciales para consultas avanzadas o personalizadas.
Punto clave: Los JOINs conectan tablas para obtener datos relacionados, una habilidad clave en bases de datos relacionales.
Actividad rápida (3 minutos):
Escribe en papel una relación 1:N que hayas visto (por ejemplo, del Módulo 4 o Lección 1). Ejemplo:
- Relación: Un estudiante (estudiantes) tiene muchos registros de asistencia (asistencias).
- Clave foránea: id_estudiante en asistencias → id en estudiantes.
Tipos de JOINs y relaciones (20 minutos)
Explicación:
Exploremos los JOINs y cómo se aplican a relaciones 1:N y N:N.
INNER JOIN:
- Devuelve registros que tienen coincidencias en ambas tablas.
- Sintaxis:
SELECT columnas FROM tabla1 INNER JOIN tabla2 ON tabla1.columna = tabla2.columna;
- Ejemplo (1:N): Usuarios y sus posts.
SELECT usuarios.nombre, posts.titulo FROM usuarios INNER JOIN posts ON usuarios.id = posts.id_usuario;
- Solo muestra usuarios que tienen posts.
LEFT JOIN:
- Devuelve todos los registros de la tabla izquierda, con coincidencias de la derecha o NULL si no hay.
- Sintaxis:
SELECT columnas FROM tabla1 LEFT JOIN tabla2 ON tabla1.columna = tabla2.columna;
- Ejemplo (1:N): Todos los usuarios, con o sin posts.
SELECT usuarios.nombre, posts.titulo FROM usuarios LEFT JOIN posts ON usuarios.id = posts.id_usuario;
- Muestra todos los usuarios; si no tienen posts, titulo es NULL.
Relaciones uno a muchos (1:N):
- Común en aplicaciones web.
- Ejemplo: Una categoría tiene muchos productos.
- Tablas: categorias (id, nombre), productos (id, nombre, id_categoria).
- Consulta:
SELECT categorias.nombre, productos.nombre FROM categorias LEFT JOIN productos ON categorias.id = productos.id_categoria;
Relaciones muchos a muchos (N:N):
- Requiere una tabla intermedia.
- Ejemplo: Estudiantes y cursos.
- Tablas:
- estudiantes (id, nombre).
- cursos (id, nombre).
- estudiantes_cursos (id_estudiante, id_curso).
- Consulta:
SELECT estudiantes.nombre, cursos.nombre FROM estudiantes INNER JOIN estudiantes_cursos ON estudiantes.id = estudiantes_cursos.id_estudiante INNER JOIN cursos ON estudiantes_cursos.id_curso = cursos.id;
- Muestra estudiantes y los cursos en los que están inscritos.
- Tablas:
Notas importantes:
- INNER JOIN es más restrictivo; LEFT JOIN es más inclusivo.
- Usa alias para simplificar: FROM usuarios AS u JOIN posts AS p ON u.id = p.id_usuario.
- Prueba consultas en phpMyAdmin para ver cómo cambian los resultados entre INNER y LEFT.
Cómo probarlo:
- Crea una base de datos pruebas en phpMyAdmin.
- Crea tablas simples:
CREATE TABLE usuarios ( id INT AUTO_INCREMENT PRIMARY KEY, nombre VARCHAR(100) NOT NULL ); CREATE TABLE posts ( id INT AUTO_INCREMENT PRIMARY KEY, titulo VARCHAR(200) NOT NULL, id_usuario INT, FOREIGN KEY (id_usuario) REFERENCES usuarios(id) ); INSERT INTO usuarios (nombre) VALUES ('Ana'), ('Juan'); INSERT INTO posts (titulo, id_usuario) VALUES ('Post 1', 1);
- Prueba:
- INNER JOIN: SELECT usuarios.nombre, posts.titulo FROM usuarios INNER JOIN posts ON usuarios.id = posts.id_usuario;
- Resultado: Solo “Ana” con “Post 1”.
- LEFT JOIN: SELECT usuarios.nombre, posts.titulo FROM usuarios LEFT JOIN posts ON usuarios.id = posts.id_usuario;
- Resultado: “Ana” con “Post 1”, “Juan” con NULL.
- INNER JOIN: SELECT usuarios.nombre, posts.titulo FROM usuarios INNER JOIN posts ON usuarios.id = posts.id_usuario;
Punto clave: Los JOINs permiten combinar datos relacionados, esenciales para consultas en aplicaciones reales.
Actividad rápida (3 minutos):
Escribe en papel una consulta INNER JOIN para unir clientes y pedidos. Solución sugerida:
SELECT clientes.nombre, pedidos.id
FROM clientes
INNER JOIN pedidos ON clientes.id = pedidos.id_cliente;
3. Ejemplo práctico: Consulta que une usuarios con sus publicaciones (15 minutos)
Explicación:
Crearemos una base de datos con usuarios y publicaciones, y usaremos JOINs para consultarlas.
Paso 1: Crear las tablas:
- En phpMyAdmin, crea la base de datos blog y ejecuta:
CREATE TABLE usuarios ( id INT AUTO_INCREMENT PRIMARY KEY, nombre VARCHAR(100) NOT NULL, email VARCHAR(100) NOT NULL UNIQUE ); CREATE TABLE posts ( id INT AUTO_INCREMENT PRIMARY KEY, titulo VARCHAR(200) NOT NULL, contenido TEXT NOT NULL, id_usuario INT, FOREIGN KEY (id_usuario) REFERENCES usuarios(id) ON DELETE CASCADE );
Paso 2: Insertar datos:
- Ejecuta:
INSERT INTO usuarios (nombre, email) VALUES ('Ana', 'ana@correo.com'), ('Juan', 'juan@correo.com'), ('María', 'maria@correo.com'); INSERT INTO posts (titulo, contenido, id_usuario) VALUES ('Mi primer post', 'Contenido del post 1', 1), ('Otro post', 'Contenido del post 2', 1), ('Post de Juan', 'Contenido del post 3', 2);
Paso 3: Consultas con JOINs:
- INNER JOIN: Usuarios con posts.
SELECT usuarios.nombre, usuarios.email, posts.titulo FROM usuarios INNER JOIN posts ON usuarios.id = posts.id_usuario;
- Resultado esperado:
+--------+--------------------+------------------+ | nombre | email | titulo | +--------+--------------------+------------------+ | Ana | ana@correo.com | Mi primer post | | Ana | ana@correo.com | Otro post | | Juan | juan@correo.com | Post de Juan | +--------+--------------------+------------------+
- Nota: María no aparece (no tiene posts).
- Resultado esperado:
- LEFT JOIN: Todos los usuarios, con o sin posts.
SELECT usuarios.nombre, usuarios.email, posts.titulo FROM usuarios LEFT JOIN posts ON usuarios.id = posts.id_usuario;
- Resultado esperado:
+--------+--------------------+------------------+ | nombre | email | titulo | +--------+--------------------+------------------+ | Ana | ana@correo.com | Mi primer post | | Ana | ana@correo.com | Otro post | | Juan | juan@correo.com | Post de Juan | | María | maria@correo.com | NULL | +--------+--------------------+------------------+
- Nota: María aparece con titulo = NULL.
- Resultado esperado:
Cómo funciona:
- INNER JOIN: Solo muestra usuarios con al menos un post (relación 1:N).
- LEFT JOIN: Incluye a todos los usuarios, útil para ver quién no ha publicado.
- ON usuarios.id = posts.id_usuario: Vincula las tablas usando la clave foránea.
Punto clave: Este ejemplo muestra cómo los JOINs recuperan datos relacionados, una práctica común en aplicaciones web como blogs.
Actividad rápida (3 minutos):
Modifica la consulta LEFT JOIN (en papel) para incluir solo el id del post. Solución sugerida:
SELECT usuarios.nombre, usuarios.email, posts.id
FROM usuarios
LEFT JOIN posts ON usuarios.id = posts.id_usuario;
Resumen y preparación para la tarea (10 minutos)
Resumen:
- Relaciones:
- Uno a muchos (1:N): Una tabla conecta con varias (por ejemplo, usuarios y posts).
- Muchos a muchos (N:N): Requiere tabla intermedia (por ejemplo, estudiantes y cursos).
- JOINs:
- INNER JOIN: Coincidencias en ambas tablas.
- LEFT JOIN: Todos los registros de la tabla izquierda.
- Ejemplo: Consultamos usuarios y sus posts con INNER y LEFT JOIN.
- Los JOINs son esenciales para combinar datos en MySQL, como en el proyecto del Módulo 4.
Preparación para la tarea:
La tarea pide crear una consulta que relacione productos y categorías.
- Estrategia:
- Usa las tablas productos y categorías (similares a las de Lección 1, Módulo 5).
- Aplica INNER JOIN o LEFT JOIN para mostrar productos con sus categorías.
- Inserta datos de prueba para verificar los resultados.
- Lógica básica:
SELECT productos.nombre, categorias.nombre FROM productos INNER JOIN categorias ON productos.id_categoria = categorias.id;
Punto clave: Practicar JOINs refuerza la capacidad de consultar datos relacionados, una habilidad clave para aplicaciones web.
Tarea práctica: Crea una consulta que relacione productos y categorías
Instrucciones:
- Usa las siguientes tablas (basadas en Lección 1, Módulo 5):
CREATE TABLE categorias ( id INT AUTO_INCREMENT PRIMARY KEY, nombre VARCHAR(50) NOT NULL ); CREATE TABLE productos ( id INT AUTO_INCREMENT PRIMARY KEY, nombre VARCHAR(100) NOT NULL, precio DECIMAL(10,2) NOT NULL, id_categoria INT, FOREIGN KEY (id_categoria) REFERENCES categorias(id) ON DELETE SET NULL );
- Inserta datos de prueba:
INSERT INTO categorias (nombre) VALUES ('Electrónica'), ('Ropa'), ('Hogar'); INSERT INTO productos (nombre, precio, id_categoria) VALUES ('Teléfono', 499.99, 1), ('Laptop', 999.99, 1), ('Camiseta', 29.99, 2), ('Sofá', 399.99, NULL);
- Escribe 2 consultas SQL con JOINs:
- Consulta 1: Usa INNER JOIN para listar productos y sus categorías (solo productos con categoría asignada).
- Consulta 2: Usa LEFT JOIN para listar todos los productos, con o sin categoría.
- Entregable:
- Un archivo de texto o documento con:
- Las 2 consultas SQL.
- Los resultados esperados (descritos o capturas de phpMyAdmin).
- Opcional: Capturas de pantalla de phpMyAdmin mostrando los resultados.
- Un archivo de texto o documento con:
- Usa el siguiente ejemplo como guía:
-- Consulta 1: INNER JOIN SELECT productos.nombre AS producto, productos.precio, categorias.nombre AS categoria FROM productos INNER JOIN categorias ON productos.id_categoria = categorias.id; -- Consulta 2: LEFT JOIN SELECT productos.nombre AS producto, productos.precio, categorias.nombre AS categoria FROM productos LEFT JOIN categorias ON productos.id_categoria = categorias.id;
- Pasos para completar:
- Paso 1: Crea la base de datos tienda en phpMyAdmin.
- Paso 2: Crea las tablas categorias y productos.
- Paso 3: Inserta los datos de prueba.
- Paso 4: Escribe las 2 consultas solicitadas.
- Paso 5: Prueba las consultas en phpMyAdmin (pestaña “SQL”).
- Verifica los resultados en la pestaña “Browse” o en la salida de la consulta.
- Paso 6: Entrega las consultas y los resultados esperados.
Ejemplo de solución esperada:
- Consultas:
-- INNER JOIN SELECT productos.nombre AS producto, productos.precio, categorias.nombre AS categoria FROM productos INNER JOIN categorias ON productos.id_categoria = categorias.id; -- LEFT JOIN SELECT productos.nombre AS producto, productos.precio, categorias.nombre AS categoria FROM productos LEFT JOIN categorias ON productos.id_categoria = categorias.id;
- Resultados esperados:
- INNER JOIN:
+------------+--------+-------------+ | producto | precio | categoria | +------------+--------+-------------+ | Teléfono | 499.99 | Electrónica | | Laptop | 999.99 | Electrónica | | Camiseta | 29.99 | Ropa | +------------+--------+-------------+
- LEFT JOIN:
+------------+--------+-------------+ | producto | precio | categoria | +------------+--------+-------------+ | Teléfono | 499.99 | Electrónica | | Laptop | 999.99 | Electrónica | | Camiseta | 29.99 | Ropa | | Sofá | 399.99 | NULL | +------------+--------+-------------+
- INNER JOIN:
Tiempo estimado: 30-45 minutos (puedes hacerlo después de la lección).
Entregable:
- Archivo de texto con las 2 consultas SQL y los resultados esperados.
- Opcional: Capturas de phpMyAdmin con los resultados.
Consejo:
- Usa alias (AS producto, AS categoria) para clarificar los nombres de las columnas.
- Prueba primero el INNER JOIN, luego el LEFT JOIN, y compara los resultados.
- Verifica los datos insertados con SELECT * FROM productos; y SELECT * FROM categorias; antes de ejecutar los JOINs.