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@postgresql.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/>