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
80 changes: 80 additions & 0 deletions resoluciones/maria-montepeque/ejercicio-86/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Ejercicio 86: ORDER BY Nivel Basico

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

## Tema central

ORDER BY

## Descripcion del problema

Una biblioteca tecnica necesita mostrar sus libros y prestamos en
distintos ordenes: por cantidad de ejemplares, y agrupados por
categoria con un segundo criterio de desempate, sin tener que
ordenarlos manualmente fuera de la base de datos.

## Tablas y relaciones

- `autores`: catalogo de autores.
- `libros`: catalogo de libros, cada uno de un autor.
- `prestamos`: tabla principal, cada prestamo de un libro. `autores`
1—N `libros`; `libros` 1—N `prestamos`.

## Uso de ORDER BY

En `dql/consultas.sql`:

1. Orden ascendente (por defecto): `ORDER BY ejemplares_totales`
ordena los libros de menos a mas ejemplares sin necesitar `ASC`
explicito.
2. Orden descendente y por varias columnas a la vez: la consulta 5
usa `ORDER BY categoria ASC, ejemplares_totales DESC`. Primero
agrupa los libros por categoria (alfabeticamente), y dentro de
cada categoria los ordena de mas a menos ejemplares. El segundo
criterio solo desempata dentro de los grupos que forma el primero.

## 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 titulo, categoria FROM libros ORDER BY 5;` falla porque la
consulta solo devuelve 2 columnas, no 5. Se valido con Python
(`sqlite3`): lanza
`1st ORDER BY term out of range - should be between 1 and 2`. Ordenar
por posicion numerica es fragil: si el orden de las columnas del
`SELECT` cambia, el `ORDER BY` termina apuntando a otra columna sin
avisar; por eso es mejor ordenar siempre por nombre.

(Se probo primero ordenar `SELECT DISTINCT categoria ... ORDER BY
titulo`, una columna fuera del resultado, pero en SQLite esa
combinacion es valida a diferencia de otros motores, asi que no sirve
como caso que falla; se reemplazo por el de la posicion fuera de
rango.)

## 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).

## Como ejecutar

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

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

-- Ejercicio 86: ORDER BY Nivel Basico
-- Tema central: ORDER BY
-- 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-86/dml/inserts.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
PRAGMA foreign_keys = ON;

-- Ejercicio 86: ORDER BY Nivel Basico
-- 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-86/dql/consultas.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.headers on
.mode column

-- Ejercicio 86: ORDER BY Nivel Basico
-- 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. Consulta con WHERE: solo los prestamos activos.
SELECT id_prestamo, id_libro, nombre_prestatario
FROM prestamos
WHERE fecha_devolucion IS NULL;

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

-- 4. Conteo o resumen: total de libros por categoria.
SELECT categoria, COUNT(*) AS total_libros
FROM libros
GROUP BY categoria;

-- 5. Validacion especifica de ORDER BY: orden descendente
-- (`DESC`) y orden por varias columnas a la vez. Primero se agrupan
-- los libros por categoria (ascendente, orden alfabetico por
-- defecto) y, dentro de cada categoria, se ordenan por cantidad de
-- ejemplares de mayor a menor (DESC). Esto demuestra que ORDER BY
-- puede combinar mas de una columna, cada una con su propia
-- direccion.
SELECT titulo, categoria, ejemplares_totales
FROM libros
ORDER BY categoria ASC, ejemplares_totales DESC;

-- Caso comentado que debe fallar (no ser recomendable), dejar
-- comentado: ordenar por la posicion de una columna que no existe en
-- el resultado (la consulta solo tiene 2 columnas, no 5). Ordenar por
-- posicion numerica en vez de por nombre es fragil: si el SELECT
-- cambia de orden, el ORDER BY termina apuntando a otra columna sin
-- avisar.
-- SELECT titulo, categoria FROM libros ORDER BY 5;
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Evidencias - Ejercicio 86

## Tema

ORDER BY

## 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-86.db < ddl/schema.sql
sqlite3 ejercicio-86.db < dml/inserts.sql
sqlite3 ejercicio-86.db < dql/consultas.sql
```

## Resultados

**3. Libros ordenados por ejemplares, ascendente (por defecto):**

```text
titulo ejemplares_totales
Clean Architecture 1
The Art of Computer Programming Vol. 1 1
Clean Code 2
Patterns of Enterprise Application Architecture 2
Refactoring 3
```

**5. Orden por dos columnas (categoria ascendente, ejemplares
descendente):**

```text
titulo categoria ejemplares_totales
The Art of Computer Programming Vol. 1 Algoritmos 1
Refactoring Arquitectura 3
Patterns of Enterprise Application Architecture Arquitectura 2
Clean Architecture Arquitectura 1
Clean Code Ingenieria 2
```

Dentro del grupo "Arquitectura" (que quedo ordenado alfabeticamente
antes que "Ingenieria"), los libros bajan de 3 a 1 ejemplares: el
segundo criterio de orden solo actua dentro de cada grupo del primero.

**Caso comentado verificado:**

- `SELECT titulo, categoria FROM libros ORDER BY 5;` → `1st ORDER BY term out of range - should be between 1 and 2` (la consulta solo tiene 2 columnas).

Nota: se probo primero un caso con `SELECT DISTINCT ... ORDER BY` de
una columna fuera del resultado, pero en SQLite esa combinacion **si
es valida** (a diferencia de otros motores como PostgreSQL), asi que
se reemplazo por el caso de la posicion fuera de rango, que si falla.

## Aprendizaje

`ORDER BY` ordena ascendente por defecto y descendente con `DESC`.
Cuando se listan varias columnas separadas por coma, cada una puede
tener su propia direccion, y la segunda columna solo desempata dentro
de los grupos que ya formo la primera (no reordena todo el resultado
de nuevo). Ordenar por la posicion numerica de una columna (`ORDER BY
5`) es fragil: si esa posicion no existe en el resultado, la consulta
falla, y aunque existiera, cualquier cambio en el orden de las
columnas del `SELECT` cambiaria el significado del `ORDER BY` sin
avisar. Por eso es mejor ordenar siempre por nombre de columna.
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Solicitud SQL - Ejercicio 086: Delivery de Comida

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

## Solicitud del cliente

Un negocio de comida recibe pedidos, repartidores, menus y
calificaciones. El cliente quiere diferenciar catalogos, operaciones y
resultados para no mezclar informacion permanente con movimientos.
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

La peticion central es de diseno: separar lo permanente (clientes,
menus, repartidores) de lo operativo (pedidos) y de lo resultante
(pagos), sin mezclar las tres capas en una sola tabla. 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`, `menus`, `repartidores`: catalogos permanentes.
- `pedidos`: operacion, cada pedido nuevo.
- `pagos`: resultado de un pedido. `UNIQUE (id_pedido)` garantiza un
solo pago oficial por pedido.

## Vista SQL

`vista_pedidos_completos` (definida en
[ddl/schema.sql](ddl/schema.sql)) junta pedido, cliente, menu,
repartidor y pago con `LEFT JOIN`, manteniendo separadas las tres
capas en un solo reporte legible.

## Como se relacionan

`clientes` 1:N `pedidos`; `menus` 1:N `pedidos`; `repartidores` 1:N
`pedidos`; `pedidos` 1:1 `pagos`. El diagrama esta en
[diagramas/diagrama-er.svg](diagramas/diagrama-er.svg).

## Que datos de prueba use

4 clientes, 5 platillos, 2 repartidores, 5 pedidos (2 `entregado` con
pago, 1 `en_camino` sin pago, 1 marcado `entregado` por error con un
pago que se corrige despues, 1 `recibido`) y 3 pagos. Tambien un
`INSERT` comentado que reproduce el problema de duplicar un pago para
el mismo pedido y debe fallar. Detalle en
[dml/inserts.sql](dml/inserts.sql).

## Que operaciones de mantenimiento incluyo

En [dml/operaciones.sql](dml/operaciones.sql): un `UPDATE` de estado
(el pedido que se marco entregado por error pasa a `cancelado`) y un
`DELETE` controlado que elimina el pago invalido de ese pedido, sin
tocar ningun pago de un pedido ya `entregado`.

## Que consultas responden al cliente

En [dql/consultas.sql](dql/consultas.sql): el resumen completo de
pedidos usando la vista, en que estado esta cada pedido, que cliente
tiene mas pedidos, los pedidos ordenados por fecha y monto, y un
reporte con `GROUP BY` + `HAVING` (tambien sobre la vista) de ingresos
totales por categoria de menu, para decidir en cual enfocar
promociones.

## 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-086.db < ddl/schema.sql
sqlite3 ejercicio-086.db < dml/inserts.sql
sqlite3 ejercicio-086.db < dml/operaciones.sql
sqlite3 ejercicio-086.db < dql/consultas.sql
```

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