SQL contra el Apocalipsis Mutante (Parte 5): Última defensa

Consulta las soluciones explicadas de los retos avanzados con funciones de ventana, CTEs y CUBE. Consultas SQL para sobrevivir al caos mutante.

Pensábamos que lo peor ya había pasado. Que después de clasificar refugios, contar infectados y trazar mapas de avistamientos podríamos respirar. Ilusos.

La tercera y última parte nos obligó a sacar toda la artillería. Ya no bastaba con consultar datos. Había que analizar patrones, construir rutas de evacuación dinámicas y generar informes multidimensionales. Y sí, todo eso con SQL.

Aquí tienes las soluciones explicadas de los últimos cinco retos. Si estás leyendo esto, es que todavía no te han comido.

Reto 3.1 – Ranking por armamento: quién manda aquí

La cosa está cada vez peor, necesitamos urgentemente asignar un número a cada refugio según la cantidad de armas que tiene. Así de simple. O así de esencial, si estás organizando una defensa coordinada y necesitas saber a quién se le puede confiar una ametralladora sin que se dispare en el pie.

Empezamos suavecito, hay que calentar. ROW_NUMBER() es una función de ventana que genera un contador dentro del conjunto de datos, según el orden que tú le digas. Aquí lo ordenamos por Weapons DESC, es decir, del más armado al menos. Cada refugio recibe un número único, sin importar si hay empates.

Esto no devuelve “quién tiene más armas”, sino quién va primero, segundo, tercero…. Una forma de tomar decisiones rápidas sin tener que pensar demasiado. Como debe ser en medio de un asalto mutante.

Reto 3.2 – Comparar infectados entre refugios vecinos

Se nos pide una labor fundamental para analizar la situación, ver si los números de infectados suben o bajan en los refugios contiguos. No para hacer turismo sanitario, sino para prever si un brote se está expandiendo.

Y ahora si, funciones de ventana de verdad, LAG(Infected, 1) devuelve el número de infectados del refugio anterior mientras que LEAD(Infected, 1) devuelve el número de infectados del siguiente. Ambos requieren un orden: en este caso, ORDER BY RefugeID.

Esta es una forma elegante de comparar filas sin tener que auto-unir la tabla consigo misma. Ideal para ver tendencias, anomalías… o refugios que están a punto de convertirse en un problema.

Reto 3.3 – Avistamientos y totales con ROLLUP

Otro imprescindible, crear un informe con los avistamientos de mutantes por día y ubicación, pero incluyendo totales parciales. ¿Por qué? Porque en el apocalipsis, igual que en el día a día en la oficina, alguien en la cadena de mando pidió “una vista agregada para facilitar la toma de decisiones” y no supimos decir que no.

En este caso ROLLUP nos permite agrupar en varios niveles:

  • Día + coordenadas → número de avistamientos
  • Día (sin coordenadas) → total de ese día
  • Total global

Esto genera filas con valores NULL en las columnas que se van agregando. Si no sabes leer esas NULL, no estás leyendo totales. Estás leyendo confusión. Lo bueno: es más limpio que hacer varias consultas. Lo malo: requiere que el que lo lea sepa lo que está viendo. No apto para jefes con prisas.

Reto 3.4 – Rutas de evacuación dinámicas con CTE recursiva

Entre los datos de infectados y los avistamientos nos empezamos a preocupar, ¿y si salir corriendo es la mejor opción? Por si acaso vamos a construir todas las rutas de evacuación posibles a partir del refugio 1, siguiendo las conexiones que tenemos en la tabla EvacuationRoutes.

Esto es una CTE recursiva de manual. Traducido: una tabla temporal que se llama a sí misma para recorrer un camino paso a paso. En la parte “ancla” seleccionamos las rutas que salen del refugio 1 mientras que en la parte recursiva vamos empalmando los destinos como si siguiéramos el hilo de Ariadna, construyendo la ruta completa en texto (Path).

CAST y CONVERT se usan aquí para concatenar el camino en una cadena legible: 1 -> 2 -> 3 -> 4 -> 5.

¿Tiene límites? Claro. Sin control de ciclos puede acabar en bucle infinito, como los correos entre departamentos. Pero para rutas simples, esto es perfecto.

Reto 3.5 – Informes multidimensionales con CUBE

Por si acaso antes de irnos vamos a sacar un último informe de situación. Nos han pedido sacar un informe de cuántos refugios hay por estado (CRITICAL u OK) y por nivel de armamento, incluyendo subtotales y totales. Porque si, a alguien le ha parecido bien hacer una tabla dinámica sin usar Excel.

Esto tiene miga, lo sé. Vamos por partes. Primero agrupamos por dos variables derivadas con CASE estado (CRITICAL o OK) y rango de armas (0–20, 21–50, >50). Después, con CUBE generamos todas las combinaciones posibles:

  • Cada grupo individual
  • Totales por estado
  • Totales por grupo de armas
  • Total general (cuando ambas columnas son NULL)

Si ROLLUP ya era potente, CUBE es una navaja suiza para informes complejos. Útil, pero peligroso si no sabes leer lo que devuelve.

Conclusión

Estas consultas no se escriben con prisas. Se escriben con estrategia. En esta última fase, SQL dejó de ser una herramienta de lectura para convertirse en un lenguaje de decisión.

Desde rutas de evacuación recursivas hasta informes multidimensionales, estas técnicas separan a los que saben ejecutar un SELECT de los que pueden liderar una operación de supervivencia basada en datos.

¿Es el final? Por ahora. La amenaza mutante ha sido contenida. Pero si algo hemos aprendido de los datos… es que siempre vuelven.Y esta vez, estaremos listos.

Publicado por Roberto Carrancio

Mi nombre es Roberto Carrancio y soy un DBA de SQL server con más de 10 años de experiencia en el sector. Soy el creador del blog soydba.es donde intento publicar varios artículos a la semana (de lunes a viernes que los fines de semana me gusta estar con mi gente y disfrutar de mi moto) Espero que disfrutes leyendo este blog tanto como yo disfruto escribiendo y que te sea de utilidad. Si tienes alguna sugerencia, pregunta o comentario, puedes dejarlo al final de cada entrada o enviarme un correo electrónico. Estaré encantado de leerte y responderte. ¡Gracias por tu visita! Mi principal interés es compartir mi conocimiento sobre bases de datos con todo el que quiera aprenderlo. Me parece un mundo tan apasionante como desconocido. Fuera de lo profesional me encanta la cocina, la moto y disfrutar de tomar una cervecita con amigos.

Deja una respuesta