| 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: | Whole Thread | Raw Message | 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/>
| 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 |