Archivo de la etiqueta: consulta

Como pivotar datos en consultas SQL

A lo largo de mi vida profesional me he encontrado con la necesidad de crear salidas de datos en las que tenia los datos por filas en las tablas de la base de datos y la representación para el usuario requería columnas. El procedimiento por el cual se transforman filas en columnas se llama “pivotar”.

Vamos a partir de un ejemplo simple. Tenemos una tabla de ventas por mes en la que se almacena 4 campos: año, mes, cantidad e importe de venta mensual.

select * from VENTAS
ANYO MES CANTIDAD IMPORTE
2000 1 223 9587.66
2000 2 458 21593.4
2000 3 625 35051.4
2000 4 600 40539.87
2000 5 425 38067.3

(Existen datos para todos los meses de los años 2000, 2001 y 2003 )

Supongamos que necesitamos los datos en una tabla cruzada de Años contra meses. La primera forma de hacerlo que se nos suele ocurrir es obtener todas las tuplas de la tabla y con el lenguaje que estemos programando ir recorriendo fila por fila e ir pintando en una tabla los datos para cada año y mes uno a uno.
Con la pivotación de estos datos podemos ahorrarnos mucho trabajo y tiempo de calculo en nuestra aplicación. Sigue leyendo Como pivotar datos en consultas SQL

Oracle: Los N primeros resultados RANK OVER

Muchas veces nos encontramos con la necesidad de sacar un “ranking” o un “top 10” de una serie de resultados. Hasta ahora yo siempre habia usado el atributo ROWNUM en la condicion de la consulta pero esto puede devolvernos valores inesperados. Esto funciona bien cuando quieres limitar el numero de registros pero no cuando quieres los N mayores/menores.
Normalmente usariamos el ROWNUM de esta manera:

SELECT id, descripcion
FROM tabla1
WHERE ROWNUM < 5 ORDER BY fecha DESC

Esto es incorrecto ya que la asignación de valor de ROWNUM se realiza antes de la ordenación, por lo tanto nos esta devolviendo un resultado erróneo. Se podría arreglar la consulta haciendo una consulta anidada que ordenara los valores y otra consulta exterior que filtrara solo los 5 primeros pero es menos óptimo que la solución siguiente.

La forma correcta de hacer esto es mediante la funcion analítica Rank()
En el siguiente ejemplo se muestra como obtener los 5 últimos resultados por fecha descendente.

SELECT id, descripcion
FROM (
SELECT RANK ()
OVER (PARTITION BY id ORDER BY fecha DESC) orden,
Id, descripcion
FROM Tabla1
)
WHERE orden < 5

Estas funciones analiticas estan disponibles en Oracle Database desde la version 8i y podeis consultar su sintaxis Funciones analíticas Rank y Dense_rank

Espero que esta explicación le sea útil a alguien, a mi al menos me ha servido para aclararme algunos conceptos sobre este tipo de funciones analíticas.