Skip site navigation (1) Skip section navigation (2)

Utilizar Window function para Running Total

From: Raúl Andrés Duque Murillo <ra_duque(at)yahoo(dot)com(dot)mx>
To: "Lista - PostgreSQL" <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Utilizar Window function para Running Total
Date: 2010-05-20 12:21:48
Message-ID: 7A26DDF879934221A265C5DDEFB8B432@Principal (view raw or flat)
Thread:
Lists: pgsql-es-ayuda
Cordial Saludo.

Tengo una sentencia de este tipo (dentro de una función):

****************************************************************************************************************
SELECT		COALESCE(salinv.id_parte, mov.id_parte) AS id_parte,
			COALESCE(salinv.codigo_parte, mov.codigo_parte) AS codigo_parte,
			COALESCE(salinv.serial_parte, mov.serial_parte) AS serial_parte,
			COALESCE(salinv.descripcion_parte, mov.descripcion_parte) AS 
descripcion_parte,
			COALESCE(salinv.descripcion_tipoparte, mov.descripcion_tipoparte) AS 
descripcion_tipoparte,
			COALESCE(salinv.id_almacen, mov.id_almacen) AS id_almacen,
			COALESCE(salinv.codigo_almacen, mov.codigo_almacen) AS codigo_almacen,
			COALESCE(salinv.descripcion_almacen, mov.descripcion_almacen) AS 
descripcion_almacen,
			COALESCE(salinv.id_localizacion, mov.id_localizacion) AS id_localizacion,
			COALESCE(salinv.codigo_localizacion, mov.codigo_localizacion) AS 
codigo_localizacion,
			COALESCE(salinv.descripcion_localizacion, mov.descripcion_localizacion) 
AS descripcion_localizacion,
			COALESCE(anno_salinvmes, 0::smallint) AS anno_salinvmes,
			COALESCE(mes_salinvmes, 0::smallint) AS mes_salinvmes,
			COALESCE(qreal_salinvmes, 0) AS qreal_salinvmes,
			COALESCE(qcomprometida_salinvmes, 0) AS qcomprometida_salinvmes,
			COALESCE(qtransito_salinvmes, 0) AS qtransito_salinvmes,
			COALESCE(qreal2_salinvmes, 0) AS qreal2_salinvmes,
			id_movimiento,
			fecha_movimiento,
			id_transac,
			codigo_transac,
			descripcion_transac,
			id_dtransac,
			id_traninve,
			codigo_traninve,
			descripcion_traninve,			campo_almacen,
			id_tipodocumento,
			descripcion_tipodocumento,
			documento_movimiento,
			itemdocu_movimiento,
			id_tercero,
			id_tipoidentificacion,
			documento_tercero,
			nombres_tercero,
			apellido1_tercero,
			apellido2_tercero,
			iduser,
			id_unidad,
			descripcion_unidad,
			afectavalor_traninve,
			signoreal,
			signocomp,
			signotran,
			signoreal2,
			cantidad_movimiento,
			cantidadreal,
			cantidadcomp,
			cantidadtran,
			cantidadreal2,
			ts,
			COALESCE(qreal_salinvmes, 0) + sum(cantidadreal) OVER (PARTITION BY 
COALESCE(salinv.id_parte, mov.id_parte), COALESCE(salinv.id_almacen, 
mov.id_almacen), COALESCE(salinv.id_localizacion, mov.id_localizacion) ORDER 
BY fecha_movimiento) AS saldoreal,
			COALESCE(qcomprometida_salinvmes, 0) + sum(cantidadcomp) OVER (PARTITION 
BY COALESCE(salinv.id_parte, mov.id_parte), COALESCE(salinv.id_almacen, 
mov.id_almacen), COALESCE(salinv.id_localizacion, mov.id_localizacion) ORDER 
BY fecha_movimiento) AS saldocomp,
			COALESCE(qtransito_salinvmes, 0) + sum(cantidadtran) OVER (PARTITION BY 
COALESCE(salinv.id_parte, mov.id_parte), COALESCE(salinv.id_almacen, 
mov.id_almacen), COALESCE(salinv.id_localizacion, mov.id_localizacion) ORDER 
BY fecha_movimiento) AS saldortran,
			COALESCE(qreal2_salinvmes, 0) + sum(cantidadreal2) OVER (PARTITION BY 
COALESCE(salinv.id_parte, mov.id_parte), COALESCE(salinv.id_almacen, 
mov.id_almacen), COALESCE(salinv.id_localizacion, mov.id_localizacion) ORDER 
BY fecha_movimiento) AS saldoreal2
	FROM		salinvmesinicial($1) salinv
			FULL JOIN movimientoview mov ON salinv.id_parte = mov.id_parte
				AND salinv.id_almacen = mov.id_almacen
				AND salinv.id_localizacion = mov.id_localizacion
	WHERE		mov.fecha_movimiento >= primeromes($1)
				AND mov.fecha_movimiento < $1 + 1
	ORDER BY	id_parte, id_almacen, id_localizacion, mov.fecha_movimiento****************************************************************************************************************

Centrándonos en los últimos 4 campos de resultado, utilizan funciones de 
ventana para ir haciendo una suma incremental particionando por id_parte, 
id_almacen y id_localizacion algo así como un running total. Leyendo la 
documentación me dice que debo utilizar un ORDER BY para modificar el frame 
del window y así poder realizar estas sumas incrementales ... por ahora he 
utilizado el campo fecha_movimiento como ordenamiento pero tengo el problema 
de que cuando varios movimientos tienen la misma fecha, utiliza todos los 
registros con la misma fecha como frame  ... lo que quisiera es que el frame 
sea cada registro pero no puedo utilizar otro campo(s) como ORDER BY de la 
ventana ya que necesito que vayan sumándose por fecha_movimiento tal como 
esta el ORDER BY general.
Tal como esta en este momento el performace es MUY similar con y sin las 
window functions, me imagino que es gracias a que se utiliza el mismo 
ordenamiento general de la sentencia, por esta razón no quisiera modificar 
el ordenamiento de la ventana generando perjuicios en el performance de la 
sentencia.

NOTA: fecha_movimiento es del tipo timestamp y funciona como una timestamp 
pero podría tener la misma fecha/hora si los movimientos se realizaron 
dentro de una misma transacción.

Alguna sugerencia? Alguna alternativa diferente a window functions?

Atentamente,

RAUL DUQUE
Bogotá, Colombia


__________ Information from ESET NOD32 Antivirus, version of virus signature database 5131 (20100520) __________

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com




pgsql-es-ayuda by date

Next:From: Juan Pablo Sandoval RiveraDate: 2010-05-20 15:18:05
Subject: Compilando librerias de PGSQL 8.4.2
Previous:From: Marco AntonioDate: 2010-05-20 04:04:06
Subject: Re: [pgsql-es-ayuda] org.postgresql.util.PSQLException: FATAL: la autentificaci��n Ident fall�� para el usuario ��postgres��

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group