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
Views: Raw Message | Whole Thread | Download mbox | Resend email
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

Browse pgsql-es-ayuda by date

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