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

Re: Consulta con saldo de la fila anterior

From: Gabriel Hermes Colina Zambra <hermeszambra(at)yahoo(dot)com>
To: "Arturo Munive \[pgsql-es-ayuda\]" <arturomunive(at)gmail(dot)com>, Postgresql <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: Consulta con saldo de la fila anterior
Date: 2007-12-31 15:30:02
Message-ID: 380946.67745.qm@web63710.mail.re1.yahoo.com (view raw or flat)
Thread:
Lists: pgsql-es-ayuda
--- "Arturo Munive [pgsql-es-ayuda]"
<arturomunive(at)gmail(dot)com> escribió:

> Abro este nuevo hilo con una idea para solucionar un
> problema que surgió 
> de otro.
> 
> Se tiene una tabla con movimientos de salida y
> entrada de productos y se 
> queiere una consulta que arroje resultados de este
> tipo
> 
> Mov   Entrada  Salida  Saldo
> 01      10            0         10
> 02      20            0         30
> 03      0              5         25
> 04      15            0         40
> 05      0            12         28        
> 
> donde el valor saldo de la segunda línea es Saldo de
> la linea 
> anterior+entrada de la segunda
> es decir 10+20 = 30
> 
> donde un valor de columna en una linea depende de un
> valor en otra 
> columna de la anterior
> 
> Al asunto puede resolverse con subconsultas pero
> como gabriel indicaba 
> en el otro hilo con la acumulación de datos se hace
> lento
> 
> Alguna solución, tablas auxiliares funciones
> "mágicas"
> 
> Si alguno de ustedes ya resolvio un problema similar
> pueden delinearnos 
> como asi puedo sacar la mejor solucion derivada de
> mi analisis y la 
> experiencia suya.
> 
> Gracias
> --
> TIP 5: ¿Has leído nuestro extenso FAQ?
>         
> http://www.postgresql.org/docs/faqs.FAQ.html
> 
Arturo tengo 3 metodos para eso y conozco 4.


Metodo uno dos views iguales y una sub consulta

"central"."cmovimientos_stock1"
"central"."cmovimientos_stock"

Metodo dos, con un alias y la misma operacion
"central"."cmovimientos_stock1"

Ahi te pongo la DDL de una de ellas y la forma en que
la invoco.

Dos contras, primero no lee la linea anterior, por
cada linea hace un sum de las anteriores. y para
desplegar una ficha en 2400000 cabezales y 500000
lineas tenes una demora de 2 minutos y algo.

CREATE OR REPLACE VIEW "central"."cmovimientos_stock"
(
    id_local,
    sucursal,
    inventario,
    id_empresa,
    empresa,
    categoria_empresa,
    id_lin,
    documento,
    serie,
    numero,
    fecha,
    id_articulo,
    entradas,
    salidas,
    precio_u)
AS
SELECT cabezales.id_local, locales.descripcion AS
sucursal,
    tipo_documentos.inventario, cabezales.id_empresa,
cempresas.empresa,
    cabezales.categoria_empresa, documentos.id_lin,
tipo_documentos.documento,
    cabezales.serie, cabezales.numero,
cabezales.fecha, documentos.id_articulo,
    CASE WHEN ((tipo_documentos.stock_cantidad)::text
= '+'::text) THEN
    documentos.cantidad ELSE (0)::double precision END
AS entradas, CASE WHEN
    ((tipo_documentos.stock_cantidad)::text =
'-'::text) THEN
    documentos.cantidad ELSE (0)::double precision END
AS salidas, CASE WHEN
    ((tipo_documentos.stock_cantidad)::text =
'+'::text) THEN (documentos.cif *
    cabezales.cotizacion) ELSE
(documentos.precio_venta_unitario *
    cabezales.cotizacion) END AS precio_u
FROM ((central.tipo_documentos JOIN
((central.cempresas JOIN central.cabezales
    ON (((cempresas.categoria_empresa =
(cabezales.categoria_empresa)::text)
    AND (cempresas.id_empresa =
cabezales.id_empresa)))) JOIN
    central.documentos ON ((cabezales.id_cab =
documentos.id_cab))) ON
    ((tipo_documentos.id_documentos =
cabezales.id_documentos))) JOIN
    central.locales ON ((locales.id_local =
cabezales.id_local)))
WHERE (((tipo_documentos.stock_cantidad)::text =
'+'::text) OR
    ((tipo_documentos.stock_cantidad)::text =
'-'::text))
ORDER BY cabezales.fecha, documentos.id_articulo,
documentos.id_lin,
    tipo_documentos.documento;


Llamada a la ficha

select central.cmovimientos_stock.id_local,
    central.cmovimientos_stock.sucursal,
    central.cmovimientos_stock.inventario,
    central.cmovimientos_stock.id_empresa,
    central.cmovimientos_stock.empresa,
    central.cmovimientos_stock.categoria_empresa,
    central.cmovimientos_stock.id_lin,
    central.cmovimientos_stock.documento,
    central.cmovimientos_stock.serie,
    central.cmovimientos_stock.numero,
    central.cmovimientos_stock.fecha,
    central.cmovimientos_stock.id_articulo,
    central.cmovimientos_stock.entradas,
    central.cmovimientos_stock.salidas,
    (select
sum(coalesce(entradas,0)-coalesce(salidas,0))
    from central.cmovimientos_stock1 where
id_articulo=
    central.cmovimientos_stock.id_articulo and
    (fecha<central.cmovimientos_stock.fecha or
(fecha=central.cmovimientos_stock.fecha
    and id_lin<central.cmovimientos_stock.id_lin)))
    as saldo,
    central.cmovimientos_stock.precio_u from
central.cmovimientos_stock
where central.cmovimientos_stock.id_articulo='100' 
order by id_articulo,fecha,id_lin


Metodo 3
Simplemente llenar la grilla de la consulta y dejar
vacio el saldo, llenando esta consulta por programa, o
sea resolverlo en el recordset o control del cliente.

Metodo 4 usar una funcion pl/pgsql que llame a la
consulta y genere un recordset con el saldo y lo
devuelva con setof.

Metodo 5 vistas materializadas, este metodo me fue
sugerido pero no lo probe aun.

Metodo 6, crear la tabla tipo vista materializada,
pero llenarla en el momento de la consulta con una
funcion pl/pgsql que recorra el select con loop donde
tenga un contador nsaldo por ejemplo y llenar la tabla
con insert, este metodo me resulto muy bien en saldos
de acreedores y deudores donde tengo incluso un if
para determinar si paso un parametro con el codigo que
quiero o con un cero se lo aplico a todos los codigos.

Con este metodo baje la consulta de 50 segundos a 0.20
ms.

Y por ahora es el que me resulta mas conveniente.

Ahora la linea anterior creo que no es posible en
postgresql, puesto que creo no tener un
previous.saldo+entrada-salida as saldo

Bueno Arturo, en este punto tengo una buena curva de
experiencia, desde el primer metodo que me sirvio
hasta que crecio el volumen de informacion, hasta este
ultimo donde creo que puedo multiplicar por 10 los
registros que hoy tengo y la performance seria igual a
la rapides de un balazo.

Suerte y feliz 2008 para todos





      ____________________________________________________________________________________
¡Capacidad ilimitada de almacenamiento en tu correo!
No te preocupes más por el espacio de tu cuenta con Correo Yahoo!:                      
http://correo.espanol.yahoo.com/

In response to

pgsql-es-ayuda by date

Next:From: Alvaro HerreraDate: 2007-12-31 17:01:43
Subject: Re: Depurar Funciones step to step.
Previous:From: Arturo MuniveDate: 2007-12-31 13:49:40
Subject: Re: Depurar Funciones step to step.

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