Re: Función recursiva

From: will <wrbutros(at)rizoma(dot)cl>
To: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Función recursiva
Date: 2012-03-06 16:10:55
Message-ID: 4F56370F.9030109@rizoma.cl
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Julio Cesar Diaz Vera: Muchísimas gracias!, el ejemplo que me diste me
ha quedado muy claro,
fuiste muy detallado y asertivo en
tu respuesta
realmente me ayudaste a resolver
el problema!
gracias! =D.

Aprovecho la instancia para confirmar que la cláusula "with recursive"
también funciona con
Postgres 8.4 (probado =P).

Les dejo la consulta final (solo hice solo unos pequeños cambios):

with recursive compuesta (barcode_madre, barcode_comp_der,
tipo_comp_der, cant_mud) as
((select barcode_madre, barcode_comp_der, tipo_comp_der, cant_mud
from componente_mc where barcode_madre = 1414000 )
UNION ALL
(select componente_mc.barcode_madre,
componente_mc.barcode_comp_der, componente_mc.tipo_comp_der,
componente_mc.cant_mud * compuesta.cant_mud
from componente_mc, compuesta
where componente_mc.barcode_madre = compuesta.barcode_comp_der)
)
select barcode_comp_der, sum(compuesta.cant_mud) as cantidad
from compuesta
where tipo_comp_der = 1
group by barcode_comp_der

Debido a que se puede requerir X cantidad de un producto compuesto,
todos sus componentes
se ven multiplicados por X.

Saludos!!

On 05/03/12 20:15, Julio Cesar Diaz Vera wrote:
> Will: si usas postgres 9 la forma más sencilla de resolver el problema
> de la recursividad es con with recursive (revisa la documentación).
> Para tu caso podrías probar algo como esto
> *with recursive compuesta as ((select * from mercancia where
> barcode_madre =1414000)
> union all
> (select mercancia.* from mercancia, compuesta where
> mercancia.barcode_madre = compuesta.barcode_comp_der)
> )
> select barcode_comp_der, sum(compuesta.cant_mud) as cantidad from
> compuesta where tipo_comp_der = 1 group by barcode_comp_der
>
> *Esto devuelve el código de barras y la cantidad de cada uno de los
> productos básicos que componen a 1414000 como 'mercadería compuesta'.
> La función para encontrar cuantos productos de este tipo tienes en el
> almacén se podría parecer a esto, aunque debes pulir algunos detalles
> para poder usarla.
>
> *create type pro_cant as (barcode bigint, disponible double precision)
>
> CREATE OR REPLACE FUNCTION obtener_stock_desde_barcode ( IN
> codigo_barras bigint)*o, tod
> * RETURNS double precision AS $$
>
> declare
> var pro_cant ;
> temporal double precision;
> disponible double precision:=100000000000;
> BEGIN
> for var in
> (with recursive compuesta as ((select * from mercancia where
> barcode_madre =$1)
> union all
> (select mercancia.* from mercancia, compuesta where
> mercancia.barcode_madre = compuesta.barcode_comp_der)
> )
> select barcode_comp_der, sum(compuesta.cant_mud) as cantidad from
> compuesta where tipo_comp_der = 1 group by barcode_comp_der)
> loop
> select into temporal stock/var.disponible FROM producto WHERE
> barcode= var.barcode;
> if temporal < disponible then *o, tod
> * disponible = temporal;
> end if;
> end loop;
>
>
> RETURN disponible; -- Retorna el valor de "disponible"
> END; $$ language plpgsql;*
>
> Saludos
> Julio
>
> El 3/5/2012 10:59 AM, will escribió:
>> Hola a todos,
>>
>> Resulta que estoy integrando en un POS (bajo la GPL) una
>> funcionalidad para vender mercaderías compuestas,
>> entendiendo por 'mercadería compuesta' a un producto integrado por
>> otros 2 o más productos,
>> tal como las ofertas, de modo que al vender esta mercadería puedo
>> rebajar el stock de sus componentes.
>> Cuando se crea la mercadería compuesta también se define la cantidad
>> de unidades de cada
>> componente que participa de ella.
>>
>> Ej: Oferta A = 2xMantquillas + 1xPan
>>
>> Hasta ahí todo bien.
>> El problema radica cuando asocio una mercadería compuesta a otra, el
>> sistema debería
>> ser capaz de recorrer todo sus componentes y sub-componentes para
>> obtener el stock
>> 'posible' del compuesto. Para ello he creado una función recursiva,
>> sin embargo no da el resultado esperado.
>>
>> Adjunto el link de la tabla de asociación:
>> http://pastebin.com/rqip8ddd
>>
>> nota: tipo 4 = compuesta,
>> tipo 1 = corriente,
>>
>> cant_mud = las unidades de la mercadería que participa del
>> compuesto.
>>
>> Esta tabla también la utilizo para asociar materias primas
>> a mercaderías derivadas de ellas
>> pero los eximo de esta explicación.
>>
>> Adjunto el link de la función:
>> http://pastebin.com/h0V1fsvy
>>
>> La función retorna el stock que corresponde cuando se consulta por
>> una mercadería
>> corriente (una normal), y cuando se consulta por una mercadería
>> compuesta integrada
>> por mercaderías corrientes.
>> Pero cuando consulto por una mercadería compuesta, donde uno de sus
>> componentes
>> es otro compuesto (incluso si este compuesto solo tiene mercaderías
>> corrientes) me retorna 0.
>>
>> En este ejemplo específico si llamo a la función se esta forma:
>>
>> select * from obtener_stock_desde_barcode(1313000)
>> resulta 10 (esta bien)
>>
>> pero si hago:
>> select * from obtener_stock_desde_barcode(1414000)
>> retorna 0, se supone que dentro de sí esta función se llama a sí
>> misma de esta forma:
>> select * from obtener_stock_desde_barcode(1313000) y da como
>> resultado 0,
>> cuando debería retornar 10.
>>
>> Ese es el problema, si ejecuto select * from
>> obtener_stock_desde_barcode(1313000)
>> me da el resultado esperado, pero no así cuando se ejecuta esa misma
>> sentencia
>> dentro de sí misma. )=
>>
>> Estaré omitiendo algo?
>> Está bien realizarlo de esta forma o existe algún proceso especial
>> para trabajar con recursividad o, tod
>> en postgresql?
>>
>> De antemano muchísimas gracias! =)
>>
>> ----
>> P.D:
>> Leí de antemando sobre esta funcionalidad
>> http://wiki.postgresql.org/wiki/CTEReadme
>> pero por lo visto no es aplicable a mi situación, puesto que no solo
>> debo consultar los datos
>> sino también calcular el stock por cada componente y subcomponente.
>> (y además porque un compuesto puede tener otro compuesto)
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> -
>> Enviado a la lista de correo pgsql-es-ayuda
>> (pgsql-es-ayuda(at)postgresql(dot)org)
>> Para cambiar tu suscripción:
>> http://www.postgresql.org/mailpref/pgsql-es-ayuda
>>
>>
>> Fin a la injusticia, LIBERTAD AHORA A NUESTROS CINCO COMPATRIOTAS QUE
>> SE ENCUENTRAN INJUSTAMENTE EN PRISIONES DE LOS EEUU!
>> http://www.antiterroristas.cu
>> http://justiciaparaloscinco.wordpress.com
>
>
>
> <http://www.antiterroristas.cu/>

In response to

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Gilberto Castillo Martínez 2012-03-06 17:42:46 Re: saludos
Previous Message Marcos Michel Martinez Perez 2012-03-06 16:00:20 saludos