Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions resoluciones/maria-montepeque/ejercicio-84/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Ejercicio 84: WHERE Nivel Intermedio

**Nombre:** Maria Jose Montepeque
**Fecha:** 2026-08-24

## Tema central

WHERE

## Descripcion del problema

Una biblioteca tecnica necesita filtros mas elaborados que "mostrar
todo": libros que no son de cierta categoria, prestamos activos
distinguidos de los devueltos, y prestamos de libros que pertenecen a
una categoria especifica, todo combinando varias condiciones a la vez.

## Tablas y relaciones

- `autores`: catalogo de autores.
- `libros`: catalogo de libros, cada uno de un autor.
- `prestamos`: tabla principal. `fecha_devolucion` queda en `NULL`
mientras el prestamo sigue activo. `autores` 1—N `libros`; `libros`
1—N `prestamos`.

## Uso de WHERE

En `dql/consultas.sql`:

1. Negacion y agrupacion: `WHERE categoria <> 'Arquitectura' AND
(ejemplares_totales > 1 OR categoria = 'Algoritmos')` usa
parentesis para controlar el orden en que se evaluan `AND` y `OR`.
2. `IS NULL` / `IS NOT NULL`: distingue prestamos activos de
devueltos, contando cada grupo con subconsultas independientes.
3. Subconsulta dentro de `WHERE ... IN (...)`: primero filtra los
libros de categoria "Arquitectura", y despues usa esa lista de ids
para filtrar los prestamos activos de esos libros especificos. A
diferencia del nivel basico, aqui la condicion de `WHERE` depende
del resultado de otra consulta completa.

## Otras restricciones aplicadas

- `PRIMARY KEY` autoincremental en las 3 tablas.
- `FOREIGN KEY`: `libros.id_autor`, `prestamos.id_libro`.
- `NOT NULL` en todas las columnas obligatorias (excepto
`fecha_devolucion`, `NULL` a proposito mientras el prestamo sigue
activo).
- `UNIQUE`: `autores.nombre_autor`.
- `CHECK`: `libros.ejemplares_totales > 0`.
- `DEFAULT` en `prestamos.fecha_prestamo`.
- `PRAGMA foreign_keys = ON;` activado al inicio del script.

## Caso que falla / no recomendable (comentado en `dql/consultas.sql`)

`SELECT * FROM libros WHERE (categoria = 'Arquitectura' AND
ejemplares_totales > 1;` falla porque el parentesis que abre antes de
`categoria` nunca se cierra. Se valido con Python (`sqlite3`): lanza
`near ";": syntax error`.

## Evidencias de ejecucion

Scripts validados en orden (`ddl` -> `inserts` -> `consultas`) con
Python (modulo `sqlite3`), ya que no se tenia el binario `sqlite3`
disponible en el entorno. Detalle completo en
[`evidencias/resultados.md`](evidencias/resultados.md).

- Datos finales: 3 autores, 5 libros, 7 prestamos (5 activos, 2
devueltos). 3 prestamos activos corresponden a libros de
Arquitectura.

## Como ejecutar

```bash
sqlite3 ejercicio-84.db < ddl/schema.sql
sqlite3 ejercicio-84.db < dml/inserts.sql
sqlite3 ejercicio-84.db < dql/consultas.sql
```

No suba archivos `.db`, `.sqlite` ni `.sqlite3`.
31 changes: 31 additions & 0 deletions resoluciones/maria-montepeque/ejercicio-84/ddl/schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
PRAGMA foreign_keys = ON;

-- Ejercicio 84: WHERE Nivel Intermedio
-- Tema central: WHERE
-- Contexto: biblioteca tecnica, prestamos de libros.

CREATE TABLE autores (
id_autor INTEGER PRIMARY KEY AUTOINCREMENT,
nombre_autor TEXT NOT NULL UNIQUE,
especialidad TEXT NOT NULL
);

CREATE TABLE libros (
id_libro INTEGER PRIMARY KEY AUTOINCREMENT,
titulo TEXT NOT NULL,
id_autor INTEGER NOT NULL,
categoria TEXT NOT NULL,
ejemplares_totales INTEGER NOT NULL CHECK (ejemplares_totales > 0),

FOREIGN KEY (id_autor) REFERENCES autores (id_autor)
);

CREATE TABLE prestamos (
id_prestamo INTEGER PRIMARY KEY AUTOINCREMENT,
id_libro INTEGER NOT NULL,
nombre_prestatario TEXT NOT NULL,
fecha_prestamo TEXT NOT NULL DEFAULT (date('now')),
fecha_devolucion TEXT,

FOREIGN KEY (id_libro) REFERENCES libros (id_libro)
);
27 changes: 27 additions & 0 deletions resoluciones/maria-montepeque/ejercicio-84/dml/inserts.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
PRAGMA foreign_keys = ON;

-- Ejercicio 84: WHERE Nivel Intermedio
-- Datos de prueba.

INSERT INTO autores (nombre_autor, especialidad) VALUES
('Robert C. Martin', 'Ingenieria de Software'),
('Donald Knuth', 'Algoritmos'),
('Martin Fowler', 'Arquitectura de Software');

INSERT INTO libros (titulo, id_autor, categoria, ejemplares_totales) VALUES
('Clean Code', 1, 'Ingenieria', 2),
('Clean Architecture', 1, 'Arquitectura', 1),
('The Art of Computer Programming Vol. 1', 2, 'Algoritmos', 1),
('Refactoring', 3, 'Arquitectura', 3),
('Patterns of Enterprise Application Architecture', 3, 'Arquitectura', 2);

INSERT INTO prestamos (id_libro, nombre_prestatario, fecha_prestamo, fecha_devolucion) VALUES
(1, 'Karla Rivas', '2026-08-01', '2026-08-10'),
(4, 'Karla Rivas', '2026-08-04', '2026-08-12');

INSERT INTO prestamos (id_libro, nombre_prestatario, fecha_prestamo) VALUES
(1, 'Bryan Solis', '2026-08-05'),
(2, 'Fernanda Lopez', '2026-08-02'),
(3, 'Jorge Cifuentes', '2026-08-03'),
(4, 'Priscila Ajanel', '2026-08-06'),
(5, 'Bryan Solis', '2026-08-07');
46 changes: 46 additions & 0 deletions resoluciones/maria-montepeque/ejercicio-84/dql/consultas.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.headers on
.mode column

-- Ejercicio 84: WHERE Nivel Intermedio
-- Consultas de validacion.

-- 1. Mostrar todos los datos principales.
SELECT p.id_prestamo, l.titulo, a.nombre_autor, p.nombre_prestatario, p.fecha_prestamo
FROM prestamos p
JOIN libros l ON l.id_libro = p.id_libro
JOIN autores a ON a.id_autor = l.id_autor;

-- 2. WHERE con negacion (<>) y agrupacion con parentesis: libros que
-- NO son de categoria 'Arquitectura', y que ademas tienen mas de un
-- ejemplar.
SELECT titulo, categoria, ejemplares_totales
FROM libros
WHERE categoria <> 'Arquitectura'
AND (ejemplares_totales > 1 OR categoria = 'Algoritmos');

-- 3. Consulta con ORDER BY: libros ordenados por cantidad de
-- ejemplares, de mayor a menor.
SELECT titulo, ejemplares_totales
FROM libros
ORDER BY ejemplares_totales DESC;

-- 4. Conteo o resumen: prestamos activos vs. devueltos, usando
-- IS NULL / IS NOT NULL.
SELECT
(SELECT COUNT(*) FROM prestamos WHERE fecha_devolucion IS NULL) AS activos,
(SELECT COUNT(*) FROM prestamos WHERE fecha_devolucion IS NOT NULL) AS devueltos;

-- 5. Validacion especifica de WHERE (nivel intermedio: subconsulta
-- dentro de WHERE con IN). Prestamos activos de libros de categoria
-- 'Arquitectura', combinando IS NULL con una subconsulta que primero
-- filtra los libros de esa categoria.
SELECT p.id_prestamo, p.nombre_prestatario, p.fecha_prestamo
FROM prestamos p
WHERE p.fecha_devolucion IS NULL
AND p.id_libro IN (
SELECT id_libro FROM libros WHERE categoria = 'Arquitectura'
);

-- Caso comentado que debe fallar (no ser recomendable), dejar
-- comentado: parentesis sin cerrar en la condicion de WHERE.
-- SELECT * FROM libros WHERE (categoria = 'Arquitectura' AND ejemplares_totales > 1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Evidencias - Ejercicio 84

## Tema

WHERE

## Comandos ejecutados

No se conto con el binario `sqlite3` en el entorno de trabajo, por lo que
la ejecucion se valido con Python (`sqlite3`), aplicando los mismos
scripts en el mismo orden:

```bash
sqlite3 ejercicio-84.db < ddl/schema.sql
sqlite3 ejercicio-84.db < dml/inserts.sql
sqlite3 ejercicio-84.db < dql/consultas.sql
```

## Resultados

**2. Libros que NO son de Arquitectura, con mas de 1 ejemplar o de
Algoritmos:**

```text
titulo categoria ejemplares_totales
Clean Code Ingenieria 2
The Art of Computer Programming Vol. 1 Algoritmos 1
```

**4. Prestamos activos vs. devueltos (`IS NULL` / `IS NOT NULL`):**

```text
activos devueltos
5 2
```

**5. Prestamos activos de libros de categoria Arquitectura
(subconsulta dentro de `WHERE ... IN`):**

```text
id_prestamo | nombre_prestatario | fecha_prestamo
4 | Fernanda Lopez | 2026-08-02
6 | Priscila Ajanel | 2026-08-06
7 | Bryan Solis | 2026-08-07
```

**Caso comentado verificado:**

- `SELECT * FROM libros WHERE (categoria = 'Arquitectura' AND ejemplares_totales > 1;` → `near ";": syntax error` (falta el parentesis de cierre).

## Aprendizaje

Ademas de `LIKE`, `BETWEEN` y fechas simuladas (nivel basico), este
ejercicio de nivel intermedio demostro `<>` (negacion), agrupacion de
condiciones con parentesis para controlar el orden en que se evaluan
`AND`/`OR`, `IS NULL`/`IS NOT NULL` para distinguir prestamos activos
de devueltos, y una subconsulta dentro de `WHERE ... IN (...)` que
primero filtra los libros de una categoria y despues usa esa lista
para filtrar los prestamos. El caso comentado muestra un error de
sintaxis muy comun: un parentesis que se abre pero nunca se cierra
rompe toda la consulta.
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Solicitud SQL - Ejercicio 084: Estudio Animacion 3D

**Nombre:** Maria Jose Montepeque
**Fecha:** 2026-08-24

## Solicitud del cliente

Un estudio maneja proyectos de animacion 3D, artistas, entregas y
estados. El cliente necesita un reporte rapido para tomar decisiones
al final de cada semana. Pidio convertir esa operacion en una base de
datos que permita consultar datos, corregir estados, registrar
movimientos y sacar reportes utiles.

## Que entendi de la solicitud

"Al final de cada semana" se tradujo en un checkpoint semanal por
proyecto (`entregas`), no solo un estado general del proyecto. Es un
nivel 5 (solicitud profesional): ademas del modelo, se pide
interpretar ambiguedad, normalizar datos, documentar decisiones y
crear al menos una vista SQL. El detalle completo del analisis esta en
[analisis/requerimiento.md](analisis/requerimiento.md).

## Que tablas cree y por que

- `clientes`: catalogo de clientes que encargan proyectos.
- `artistas`: catalogo de artistas del estudio.
- `proyectos`: tabla transaccional, cada proyecto de animacion.
- `tareas`: detalle de trabajo especifico de un artista en un
proyecto.
- `entregas`: checkpoint semanal de avance. `UNIQUE (id_proyecto,
semana)` garantiza un solo reporte oficial por semana por proyecto.

## Vista SQL

`vista_reporte_semanal` (definida en
[ddl/schema.sql](ddl/schema.sql)) junta entregas, proyecto y cliente
en una sola consulta, respondiendo directamente "que paso esta semana
en cada proyecto".

## Como se relacionan

`clientes` 1:N `proyectos`; `proyectos` 1:N `tareas`; `artistas` 1:N
`tareas`; `proyectos` 1:N `entregas`. El diagrama esta en
[diagramas/diagrama-er.svg](diagramas/diagrama-er.svg).

## Que datos de prueba use

3 clientes, 4 artistas, 3 proyectos, 8 tareas (incluida una cargada
por error para un alcance que el cliente cancelo) y 4 entregas
semanales (1 sin aprobar todavia). Tambien un `INSERT` comentado que
reproduce el problema de duplicar el checkpoint semanal y debe
fallar. Detalle en [dml/inserts.sql](dml/inserts.sql).

## Que operaciones de mantenimiento incluyo

En [dml/operaciones.sql](dml/operaciones.sql): un `DELETE` controlado
que elimina la tarea del alcance cancelado, y un `UPDATE` de estado
(la entrega semanal pendiente se aprueba una vez revisada).

## Que consultas responden al cliente

En [dql/consultas.sql](dql/consultas.sql): el reporte semanal completo
usando la vista, en que estado esta cada proyecto, que artista tiene
mas horas trabajadas, las tareas ordenadas por fecha, y un reporte con
`GROUP BY` + `HAVING` de horas totales por proyecto, para decidir
donde reforzar el equipo.

## Evidencias

Resultados de ejecutar todo en orden, incluyendo la verificacion del
caso de duplicado y de las operaciones de mantenimiento, en
[evidencias/resultados.md](evidencias/resultados.md).

## Como ejecutar

```bash
sqlite3 ejercicio-084.db < ddl/schema.sql
sqlite3 ejercicio-084.db < dml/inserts.sql
sqlite3 ejercicio-084.db < dml/operaciones.sql
sqlite3 ejercicio-084.db < dql/consultas.sql
```

No suba archivos `.db`, `.sqlite`, `.sqlite3` ni `.dump`.
Loading
Loading