diff --git a/resoluciones/antonio-canux/ejercicio-07/README.md b/resoluciones/antonio-canux/ejercicio-07/README.md new file mode 100644 index 00000000..c2463941 --- /dev/null +++ b/resoluciones/antonio-canux/ejercicio-07/README.md @@ -0,0 +1,31 @@ +# Ejercicio 07: Academia de Cursos + +**Camper:** Antonio Canux + +## Descripcion del problema + +La academia necesita reemplazar el registro manual de cursos, instructores, estudiantes y matriculas por una base de datos relacional que evite duplicidad y permita dar seguimiento academico a cada estudiante. + +## Tablas y relaciones + +- `instructores`: catalogo de instructores (nombre, correo). +- `cursos`: catalogo de cursos que dicta cada instructor (`instructores` 1—N `cursos`). +- `estudiantes`: catalogo de estudiantes (nombre, correo). +- `matriculas`: inscripcion de un estudiante a un curso con su nota y estado (`estudiantes` 1—N `matriculas`, `cursos` 1—N `matriculas`). + +## Restricciones aplicadas + +- `PRIMARY KEY` autoincremental en las 4 tablas. +- `FOREIGN KEY`: `cursos.id_instructor`, `matriculas.id_estudiante`, `matriculas.id_curso`. +- `NOT NULL` en todos los campos obligatorios. +- `UNIQUE`: `instructores.correo`, `cursos.nombre`, `estudiantes.correo`, `(id_estudiante, id_curso)` en `matriculas`. +- `CHECK`: `cursos.duracion_horas > 0`, `cursos.modalidad IN (...)`, `matriculas.nota_final BETWEEN 0 AND 100`, `matriculas.estado IN (...)`. + +## Como ejecutar + +```bash +sqlite3 ejercicio-07.db < ddl/schema.sql +sqlite3 ejercicio-07.db < dml/inserts.sql +sqlite3 ejercicio-07.db < dml/operaciones.sql +sqlite3 ejercicio-07.db < dql/consultas.sql +``` diff --git a/resoluciones/antonio-canux/ejercicio-07/ddl/schema.sql b/resoluciones/antonio-canux/ejercicio-07/ddl/schema.sql new file mode 100644 index 00000000..2ec5a0a4 --- /dev/null +++ b/resoluciones/antonio-canux/ejercicio-07/ddl/schema.sql @@ -0,0 +1,34 @@ +PRAGMA foreign_keys = ON; + +CREATE TABLE instructores ( + id_instructor INTEGER PRIMARY KEY AUTOINCREMENT, + nombre TEXT NOT NULL, + correo TEXT NOT NULL UNIQUE +); + +CREATE TABLE cursos ( + id_curso INTEGER PRIMARY KEY AUTOINCREMENT, + id_instructor INTEGER NOT NULL, + nombre TEXT NOT NULL UNIQUE, + duracion_horas INTEGER NOT NULL CHECK (duracion_horas > 0), + modalidad TEXT NOT NULL CHECK (modalidad IN ('presencial', 'virtual', 'hibrida')), + FOREIGN KEY (id_instructor) REFERENCES instructores (id_instructor) +); + +CREATE TABLE estudiantes ( + id_estudiante INTEGER PRIMARY KEY AUTOINCREMENT, + nombre TEXT NOT NULL, + correo TEXT NOT NULL UNIQUE +); + +CREATE TABLE matriculas ( + id_matricula INTEGER PRIMARY KEY AUTOINCREMENT, + id_estudiante INTEGER NOT NULL, + id_curso INTEGER NOT NULL, + fecha_matricula TEXT NOT NULL, -- ISO 'YYYY-MM-DD' + nota_final REAL CHECK (nota_final >= 0 AND nota_final <= 100), + estado TEXT NOT NULL DEFAULT 'activa' CHECK (estado IN ('activa', 'aprobada', 'reprobada', 'retirada')), + FOREIGN KEY (id_estudiante) REFERENCES estudiantes (id_estudiante), + FOREIGN KEY (id_curso) REFERENCES cursos (id_curso), + UNIQUE (id_estudiante, id_curso) +); diff --git a/resoluciones/antonio-canux/ejercicio-07/diagramas/diagrama-ER.webp b/resoluciones/antonio-canux/ejercicio-07/diagramas/diagrama-ER.webp new file mode 100644 index 00000000..c6e3cd65 Binary files /dev/null and b/resoluciones/antonio-canux/ejercicio-07/diagramas/diagrama-ER.webp differ diff --git a/resoluciones/antonio-canux/ejercicio-07/dml/inserts.sql b/resoluciones/antonio-canux/ejercicio-07/dml/inserts.sql new file mode 100644 index 00000000..393761a9 --- /dev/null +++ b/resoluciones/antonio-canux/ejercicio-07/dml/inserts.sql @@ -0,0 +1,33 @@ +INSERT INTO instructores (nombre, correo) + VALUES ('Carlos Fuentes', 'carlos.fuentes@academia.com'), + ('Laura Jimenez', 'laura.jimenez@academia.com'), + ('Miguel Torres', 'miguel.torres@academia.com'), + ('Paola Castillo', 'paola.castillo@academia.com'), + ('Ricardo Vela', 'ricardo.vela@academia.com'); + +INSERT INTO estudiantes (nombre, correo) + VALUES ('Fernanda Ortiz', 'fernanda.ortiz@correo.com'), + ('Sebastian Ruiz', 'sebastian.ruiz@correo.com'), + ('Camila Herrera', 'camila.herrera@correo.com'), + ('Andres Molina', 'andres.molina@correo.com'), + ('Daniela Soto', 'daniela.soto@correo.com'); + +INSERT INTO cursos (id_instructor, nombre, duracion_horas, modalidad) + VALUES (1, 'Fundamentos de SQL', 40, 'virtual'), + (2, 'JavaScript basico', 60, 'presencial'), + (3, 'Python para datos', 80, 'hibrida'), + (4, 'Bases de datos avanzadas', 50, 'virtual'), + (5, 'Introduccion a Git', 20, 'virtual'), + (1, 'Modelado relacional', 30, 'presencial'); + +INSERT INTO matriculas (id_estudiante, id_curso, fecha_matricula, nota_final, estado) + VALUES (1, 1, '2026-06-01', 92, 'aprobada'), + (2, 1, '2026-06-01', 55, 'reprobada'), + (3, 2, '2026-06-02', 88, 'aprobada'), + (4, 2, '2026-06-02', NULL, 'activa'), + (5, 3, '2026-06-03', 75, 'aprobada'), + (1, 3, '2026-06-03', NULL, 'activa'), + (2, 4, '2026-06-04', 60, 'aprobada'), + (3, 5, '2026-06-05', NULL, 'retirada'), + (4, 6, '2026-06-06', 95, 'aprobada'), + (5, 6, '2026-06-06', 40, 'reprobada'); diff --git a/resoluciones/antonio-canux/ejercicio-07/dml/operaciones.sql b/resoluciones/antonio-canux/ejercicio-07/dml/operaciones.sql new file mode 100644 index 00000000..61b1f7d2 --- /dev/null +++ b/resoluciones/antonio-canux/ejercicio-07/dml/operaciones.sql @@ -0,0 +1,19 @@ +INSERT INTO instructores (nombre, correo) VALUES + ('Elena Vargas', 'elena.vargas@academia.com'); + +INSERT INTO matriculas (id_estudiante, id_curso, fecha_matricula, nota_final, estado) VALUES + (2, 5, '2026-06-07', NULL, 'activa'); + +UPDATE matriculas +SET nota_final = 82, estado = 'aprobada' +WHERE id_matricula = 6; + +UPDATE cursos +SET duracion_horas = 45 +WHERE id_curso = 1; + +DELETE FROM matriculas +WHERE estado = 'retirada'; + +DELETE FROM matriculas +WHERE id_matricula = 11; diff --git a/resoluciones/antonio-canux/ejercicio-07/dql/consultas.sql b/resoluciones/antonio-canux/ejercicio-07/dql/consultas.sql new file mode 100644 index 00000000..f9ba9683 --- /dev/null +++ b/resoluciones/antonio-canux/ejercicio-07/dql/consultas.sql @@ -0,0 +1,21 @@ +SELECT * FROM matriculas; + +SELECT fecha_matricula, estado FROM matriculas; + +SELECT * FROM matriculas WHERE nota_final >= 80; + +SELECT * FROM matriculas ORDER BY fecha_matricula; + +SELECT * FROM matriculas +WHERE nota_final IS NOT NULL +ORDER BY nota_final DESC +LIMIT 5; + +SELECT COUNT(*) AS total_matriculas FROM matriculas; + +SELECT + AVG(nota_final) AS promedio, + MIN(nota_final) AS minimo, + MAX(nota_final) AS maximo +FROM matriculas +WHERE nota_final IS NOT NULL;