Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

inner join con union

Estas en el tema de inner join con union en el foro de Mysql en Foros del Web. Buenas, tengo una consulta para hacerles y ver si me pueden orientar en que estoy confundido, es lo siguiente: Tengo dos 4 tablas identicas pero ...
  #1 (permalink)  
Antiguo 01/09/2013, 20:42
 
Fecha de Ingreso: enero-2011
Mensajes: 41
Antigüedad: 13 años, 3 meses
Puntos: 0
inner join con union

Buenas, tengo una consulta para hacerles y ver si me pueden orientar en que estoy confundido, es lo siguiente:

Tengo dos 4 tablas identicas pero con distintos contenidos (mov_articulos, mov_factura, mov_prov_articulos y mov_prov_factura) necesito hacer una consulta relacionando datos entre ellas pero mostrarlas en una misma tabla calculando un numero, lo que hice es lo siguiente:

Código MySQL:
Ver original
  1. SELECT mov_articulos.prod_cod, mov_articulos.prod_nom,  SUM(mov_articulos.prod_cant) AS egresos
  2. FROM mov_articulos
  3. INNER JOIN mov_factura
  4. ON mov_factura.nro_factura = mov_articulos.id_comp
  5. WHERE tipo_comp = '1'
  6. GROUP BY mov_articulos.prod_cod
  7.        
  8.        
  9. SELECT 0,0, SUM(mov_prov_articulos.prod_cant) AS ingresos
  10. FROM mov_prov_articulos
  11. INNER JOIN mov_prov_factura
  12. ON mov_prov_factura.nro_factura = mov_prov_articulos.id_comp
  13. WHERE tipo_comp = '1'
  14. GROUP BY mov_prov_articulos.prod_cod

Tengo un while y lo que muestro en el codigo php de la tabla es esto:

Cita:
Editado: Código de programación OFF TOPIC en foros de BBDD
el problema es que los selects solos funcionan bien, pero en conjunto EL SEGUNDO no se muestra no importa en que orden los escriba, es decir en este caso no puedo recuperar el SUM "ingresos".

estoy haciendo algo mal con el union???

muchas gracias por la ayuda!

Última edición por gnzsoloyo; 02/09/2013 a las 07:38
  #2 (permalink)  
Antiguo 02/09/2013, 07:34
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: inner join con union

Código MySQL:
Ver original
  1. (SELECT mov_articulos.prod_cod, mov_articulos.prod_nom,  SUM(mov_articulos.prod_cant) AS egresos
  2.     FROM mov_articulos
  3.     INNER JOIN mov_factura
  4.     ON mov_factura.nro_factura = mov_articulos.id_comp
  5.     WHERE tipo_comp = 1
  6.     GROUP BY mov_articulos.prod_cod)
  7.            
  8.     UNION
  9.            
  10.     (SELECT 0,0, SUM(mov_prov_articulos.prod_cant) AS ingresos
  11.     FROM mov_prov_articulos
  12.     INNER JOIN mov_prov_factura
  13.     ON mov_prov_factura.nro_factura = mov_prov_articulos.id_comp
  14.     WHERE tipo_comp = 1
  15.     GROUP BY mov_prov_articulos.prod_cod)

He añadido los paréntesis y quitado las comillas del número, pero creo que el problema es ese 0, 0. No tiene mucho sentido para mí y son números, mientras que los primeros dos campos del otro select parece que son un código de producto que no sé si es texto o número, y el otro nombre de un producto. Por otra parte, ese 0, 0 no te devolverá nada más que eso 0, 0. Piensa que unirás 0 con mov_articulos.prod_cod y 0 mov_articulos.prod_nom, es decir, aparecerán como lo mismo. La unión no tiene mucho sentido ahí. Acláranos por qué usas ese 0, 0.
  #3 (permalink)  
Antiguo 03/09/2013, 21:43
 
Fecha de Ingreso: enero-2011
Mensajes: 41
Antigüedad: 13 años, 3 meses
Puntos: 0
Respuesta: inner join con union

Cita:
Iniciado por jurena Ver Mensaje
[HIGHLIGHT="MySQL"]

He añadido los paréntesis y quitado las comillas del número, pero creo que el problema es ese 0, 0. No tiene mucho sentido para mí y son números, mientras que los primeros dos campos del otro select parece que son un código de producto que no sé si es texto o número, y el otro nombre de un producto. Por otra parte, ese 0, 0 no te devolverá nada más que eso 0, 0. Piensa que unirás 0 con mov_articulos.prod_cod y 0 mov_articulos.prod_nom, es decir, aparecerán como lo mismo. La unión no tiene mucho sentido ahí. Acláranos por qué usas ese 0, 0.
Buenas, aclaro lo de 0,0 lo uso como constantes para que no me de un error ya que los select a unir tienen distintas cantidades de elemento, es decir el error seria: "The used SELECT statements have a different number of columns" si no hago eso, puedo poner campos de la tabla para rellenar el agujero pero no varia en nada mi problema =/

hice la siguiente prueba usando datos para remplazar el 0,0 :

Código MySQL:
Ver original
  1. (SELECT mov_articulos.prod_cod, mov_articulos.prod_nom,  SUM(mov_articulos.prod_cant) AS egresos
  2.         FROM mov_articulos
  3.         INNER JOIN mov_factura
  4.         ON mov_factura.nro_factura = mov_articulos.id_comp
  5.         WHERE tipo_comp = 1
  6.         GROUP BY mov_articulos.prod_cod)
  7.                
  8.         UNION
  9.                
  10.         (SELECT mov_prov_articulos.prod_cod, mov_prov_articulos.prod_nom, SUM(mov_prov_articulos.prod_cant) AS ingresos
  11.         FROM mov_prov_articulos
  12.         INNER JOIN mov_prov_factura
  13.         ON mov_prov_factura.nro_factura = mov_prov_articulos.id_comp
  14.         WHERE tipo_comp = 1
  15.         GROUP BY mov_prov_articulos.prod_cod)

Pero no vario nada aun.

Última edición por freedert; 03/09/2013 a las 21:50
  #4 (permalink)  
Antiguo 04/09/2013, 00:25
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: inner join con union

freedert,
para hacer alguna prueba, necesito aclaraciones:
mov_articulos: prod_cod, prod_nom, prod_cant, id_comp (relacionado con nro_factura de mov_factura), tipo_comp
mov_factura: nro_factura
mov_prov_articulos: prod_cod, prod_nom, prod_cant, id_comp (relacionado con nro_factura de mov_prov_factura, tipo_comp
mov_prov_factura: nro_factura
En negritas van las tablas y detrás sus campos. ¿Es así tu estructura?
¿Has probado a quitar el alias egresos? ¿qué ocurre?
  #5 (permalink)  
Antiguo 04/09/2013, 11:10
 
Fecha de Ingreso: enero-2011
Mensajes: 41
Antigüedad: 13 años, 3 meses
Puntos: 0
Respuesta: inner join con union

Si es correcta la estructura tal como la describis. Se recupera los datos de mov_articulos (o mov_prov) la cual se relaciona con mov_factura con nro_factura que es el campo compartido y luego tenemos las tablas de "_prov" que son identicas en estructura que las anteriores.

Si ya probe sacarles uno o ambos alias, en vez de llamarlos con "egresos" o "ingresos" los llamo como SUM(mov_articulos.prod_cant) desde el php, pero no varia en nada, el segundo select siempre esta vacio de resultados.

Es decir, no solo el SUM no contiene resultados, sino los otros valores que recupere en el segundo select como mov_prov_articulos.prod_cod tampoco tienen contenido.
  #6 (permalink)  
Antiguo 04/09/2013, 11:49
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: inner join con union

Por lo pronto, el uso de GROUP BY intermedios peude darte problemas, ya que toda clausula final genera consolidaciones. Por ello debes generar subconsultas con cada SELECT.
Por otro lado, el UNION puede genera errores porque tiene el comportamiento de un DISTINCT: Descarta registros con iguales valores (improbables pero no imposibles)
Yo te sugeriría, antes de avanzar, probar:
Código MySQL:
Ver original
  1. SELECT   prod_cod,
  2.          prod_nom,
  3.          egresos
  4.     (SELECT   mov_articulos.prod_cod,
  5.              mov_articulos.prod_nom,
  6.              SUM (mov_articulos.prod_cant) egresos
  7.         FROM mov_articulos INNER JOIN mov_factura
  8.              ON mov_factura.nro_factura = mov_articulos.id_comp
  9.        WHERE tipo_comp = '1'
  10.     GROUP BY mov_articulos.prod_cod) T1
  11.     UNION ALL
  12. SELECT   prod_cod,
  13.          prod_nom,
  14.          inresos
  15.     (SELECT   0 prod_cod,
  16.              '' prod_nom,
  17.              SUM (mov_prov_articulos.prod_cant) ingresos
  18.         FROM mov_prov_articulos INNER JOIN mov_prov_factura
  19.              ON mov_prov_factura.nro_factura = mov_prov_articulos.id_comp
  20.        WHERE tipo_comp = '1'
  21.     GROUP BY mov_prov_articulos.prod_cod) T2
  22. ;
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 04/09/2013, 12:39
 
Fecha de Ingreso: enero-2011
Mensajes: 41
Antigüedad: 13 años, 3 meses
Puntos: 0
Respuesta: inner join con union

gnzsoloyo, probando tu configuracion no tengo otro resultado que el de siempre.

Sera que el problema esta con el UNION? las 2 consultas select hacen referencia a 4 tablas que son identicas, es decir las tablas "mov_factura" es identica a la "mov_prov_factura" lo que difiere son los datos en ellas.
  #8 (permalink)  
Antiguo 04/09/2013, 12:56
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: inner join con union

¿Por qué no partimos de una base más simple?:
Ejecuta cada select por separado, y dinos qué resultados se obtienen en cada uno.
- Si al menos una de las queries no devuelve lo que esperas, es un error en su definición.
- Si devuelven el resultado esperado, pero luego no lo visualizas correctamente, será mejor que nos expliques el contexto real, y nos des un ejemplo de datos y la estructura de las tablas.

Por cierto: No nos olvidemos que no podemos descartar el impacto de datos defectuosos en las variables que uses en la aplicación, por lo que hay un margen de error no atribuible a MySQL ni a la consulta.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #9 (permalink)  
Antiguo 04/09/2013, 14:59
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: inner join con union

he replicado tu estructura en la medida en que he podido, he incluido datos y he probado esta consulta que tú probaste, y el resultado sí ha sido el esperado.
Código MySQL:
Ver original
  1. (SELECT mov_articulos.prod_cod, mov_articulos.prod_nom,  SUM(mov_articulos.prod_cant) AS egresos
  2.         FROM mov_articulos
  3.         INNER JOIN mov_factura
  4.         ON mov_factura.nro_factura = mov_articulos.id_comp
  5.         WHERE tipo_comp = 1
  6.         GROUP BY mov_articulos.prod_cod)
  7.                
  8.         UNION
  9.                
  10.         (SELECT mov_prov_articulos.prod_cod, mov_prov_articulos.prod_nom, SUM(mov_prov_articulos.prod_cant) AS ingresos
  11.         FROM mov_prov_articulos
  12.         INNER JOIN mov_prov_factura
  13.         ON mov_prov_factura.nro_factura = mov_prov_articulos.id_comp
  14.         WHERE tipo_comp = 1
  15.         GROUP BY mov_prov_articulos.prod_cod)
  #10 (permalink)  
Antiguo 04/09/2013, 21:06
 
Fecha de Ingreso: enero-2011
Mensajes: 41
Antigüedad: 13 años, 3 meses
Puntos: 0
Respuesta: inner join con union

Cita:
Iniciado por gnzsoloyo Ver Mensaje
¿Por qué no partimos de una base más simple?:
Ejecuta cada select por separado, y dinos qué resultados se obtienen en cada uno.
- Si al menos una de las queries no devuelve lo que esperas, es un error en su definición.
- Si devuelven el resultado esperado, pero luego no lo visualizas correctamente, será mejor que nos expliques el contexto real, y nos des un ejemplo de datos y la estructura de las tablas.

Por cierto: No nos olvidemos que no podemos descartar el impacto de datos defectuosos en las variables que uses en la aplicación, por lo que hay un margen de error no atribuible a MySQL ni a la consulta.

Bien, el tema es este, si yo agarro el 1er select, y lo ejecuto solo funciona a la perfeccion, si agarro el segundo y lo ejecuto tambien solo funciona perfecto tambien. el tema es cuando los pongo juntos en el union es cuando no andan, y el segundo siempre es el que no se muestra, ojo probe invertirlos y siempre es el de abajo el que no se muestra no importa cual ponga en que lugar.

Por ese motivo creo que es una cuestion de datos que se estan pisando, algun error conceptual en el union o algo asi.

Yo se que puedo solucionar este problema haciendo que el php actue dentro del while con otras consultas secundarias sin problema, pero me da bronca no poder lograr esta instruccion que se supone es el metodo correcto de obtener los datos que necesito verdad?.
  #11 (permalink)  
Antiguo 04/09/2013, 21:22
 
Fecha de Ingreso: enero-2011
Mensajes: 41
Antigüedad: 13 años, 3 meses
Puntos: 0
Respuesta: inner join con union

Cita:
Iniciado por jurena Ver Mensaje
he replicado tu estructura en la medida en que he podido, he incluido datos y he probado esta consulta que tú probaste, y el resultado sí ha sido el esperado.
Código MySQL:
Ver original
  1. (SELECT mov_articulos.prod_cod, mov_articulos.prod_nom,  SUM(mov_articulos.prod_cant) AS egresos
  2.         FROM mov_articulos
  3.         INNER JOIN mov_factura
  4.         ON mov_factura.nro_factura = mov_articulos.id_comp
  5.         WHERE tipo_comp = 1
  6.         GROUP BY mov_articulos.prod_cod)
  7.                
  8.         UNION
  9.                
  10.         (SELECT mov_prov_articulos.prod_cod, mov_prov_articulos.prod_nom, SUM(mov_prov_articulos.prod_cant) AS ingresos
  11.         FROM mov_prov_articulos
  12.         INNER JOIN mov_prov_factura
  13.         ON mov_prov_factura.nro_factura = mov_prov_articulos.id_comp
  14.         WHERE tipo_comp = 1
  15.         GROUP BY mov_prov_articulos.prod_cod)

Bien hice las siguientes pruebas directamente en la sql del server en vez de en el php para descartar algun error en esa parte. Y descubri algo a ver si a ustedes les cierre, hice esta prueba:

consulte:
Código MySQL:
Ver original
  1. SELECT mov_articulos.prod_cod, mov_articulos.prod_nom, SUM( mov_articulos.prod_cant ) AS egresos
  2. FROM mov_articulos
  3. INNER JOIN mov_factura ON mov_factura.nro_factura = mov_articulos.id_comp
  4. WHERE tipo_comp =1
  5. GROUP BY mov_articulos.prod_cod

RESULTADO: devuelve datos en estas tres columnas: (10 resultados)
prod_cod
prod_nom
egresos

luego consulte:
Código MySQL:
Ver original
  1. (SELECT mov_prov_articulos.prod_cod, mov_prov_articulos.prod_nom, SUM(mov_prov_articulos.prod_cant) AS ingresos
  2.         FROM mov_prov_articulos
  3.         INNER JOIN mov_prov_factura
  4.         ON mov_prov_factura.nro_factura = mov_prov_articulos.id_comp
  5.         WHERE tipo_comp = 1
  6.         GROUP BY mov_prov_articulos.prod_cod)

RESULTADO: Me dio otros datos con estas columnas: (1046 resultados)
prod_cod / prod_nom / ingresos

y por ultimo consulto todo el codigo:
Código MySQL:
Ver original
  1. (SELECT mov_articulos.prod_cod, mov_articulos.prod_nom,  SUM(mov_articulos.prod_cant) AS egresos
  2.         FROM mov_articulos
  3.         INNER JOIN mov_factura
  4.         ON mov_factura.nro_factura = mov_articulos.id_comp
  5.         WHERE tipo_comp = 1
  6.         GROUP BY mov_articulos.prod_cod)
  7.                
  8.         UNION
  9.                
  10.         (SELECT mov_prov_articulos.prod_cod, mov_prov_articulos.prod_nom, SUM(mov_prov_articulos.prod_cant) AS ingresos
  11.         FROM mov_prov_articulos
  12.         INNER JOIN mov_prov_factura
  13.         ON mov_prov_factura.nro_factura = mov_prov_articulos.id_comp
  14.         WHERE tipo_comp = 1
  15.         GROUP BY mov_prov_articulos.prod_cod)

RESULTADO: mismas tres columnas que el principio pero ojo con 1056 resultados.
prod_cod
prod_nom
egresos

Es decir me esta mostrando los resutlados convinados correctamente. Sera que el UNION esta juntando los resultados en uno solo (el primero) y no me deja llamarlos por separado? por eso el segundo alias "ingresos" no tiene contenido??

creo que ahi estaba el problema.. que piensan? de ser asi quizas no pueda recuperar los dos campos por separado y necesite hacer una consulta aparte.
  #12 (permalink)  
Antiguo 05/09/2013, 00:11
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: inner join con union

¿Has probado cambiando el orden para ver qué pasa?

Código MySQL:
Ver original
  1. (SELECT mov_prov_articulos.prod_cod, mov_prov_articulos.prod_nom, SUM(mov_prov_articulos.prod_cant) AS ingresos
  2.         FROM mov_prov_articulos
  3.         INNER JOIN mov_prov_factura
  4.         ON mov_prov_factura.nro_factura = mov_prov_articulos.id_comp
  5.         WHERE tipo_comp = 1
  6.         GROUP BY mov_prov_articulos.prod_cod)
  7.                
  8.  
  9. (SELECT mov_articulos.prod_cod, mov_articulos.prod_nom,  SUM(mov_articulos.prod_cant) AS egresos
  10.         FROM mov_articulos
  11.         INNER JOIN mov_factura
  12.         ON mov_factura.nro_factura = mov_articulos.id_comp
  13.         WHERE tipo_comp = 1
  14.         GROUP BY mov_articulos.prod_cod)
  #13 (permalink)  
Antiguo 05/09/2013, 03:34
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: inner join con union

Cita:
RESULTADO: mismas tres columnas que el principio pero ojo con 1056 resultados.
Perdón, pero ¿tu esperabas tener mas columnas, y no más registros?
Son dos cosas diferentes. Un UNION encadena un resultado a continuación del otro, poniendo las columnas en el mismo orden. Por eso tiene que tener la misma cantidad de columnas uno que otro.
Si lo que quieres es que cada producto salta en el mismo registro, con las columnas correspondientes a movimientos de venta y compra, eso es un JOIN, no un UNION.

Cita:
Es decir me esta mostrando los resutlados convinados correctamente. Sera que el UNION esta juntando los resultados en uno solo (el primero) y no me deja llamarlos por separado? por eso el segundo alias "ingresos" no tiene contenido??
UNION, como ya te dije, y @jurena te vuelve a aclarar, suprime duplicados formales, esto es, registros donde los todos valores en cada columna se repiten entre dos o más registros (y en el mismo orden).
UNION ALL, las encadena sin considerar duplicados aparentes. De allí que la cantida de registros devueltos sea mayor (cuando ambas devuelven algo)

Creo que no estás explicando correctamente lo que estás intentando hacer.
Describe mejor cuál es el resultdo esperado y qué es lo que se supone que harás con ese: un reporte, informe o visualizar qué tipo de info.
Saber lo que quieres hacer puede ayudarnos a entender el objetivo logico de tu trabajo.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #14 (permalink)  
Antiguo 05/09/2013, 07:53
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: inner join con union

Pienso, como @gnzsoloyo, que lo que quieres no es una consulta de union, sino otro tipo de consulta. Me inclino por pensar que lo que quieres es sacar en una misma línea los datos de cada producto, los ingresos y los egresos. Para eso no tienes que hacer union, sino un LEFT join de la tabla productos con el de la tabla mov_productos, relacionadas por el código del producto, pero deberías aclararnos con un ejemplo de tus datos y con la salida que deseas, qué quieres exactamente y por qué aparece aquí la factura.
  #15 (permalink)  
Antiguo 05/09/2013, 08:17
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: inner join con union

Agregaría un detalle: Para realizar un reporte de movimiento de ingresos y egresos por productos, necesitas sí o si usar la tabla de productos, y no solamente la de movimientos, porque el que haya egresos de productos no implica necesariamente que haya ingresos del mismo producto, para el mismo período. Son acciones distintas, y sólo la tabla de productos puede permitir obtener ambos al mismo tiempo.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #16 (permalink)  
Antiguo 05/09/2013, 11:24
 
Fecha de Ingreso: enero-2011
Mensajes: 41
Antigüedad: 13 años, 3 meses
Puntos: 0
Respuesta: inner join con union

Bien lo que dice jurena es exactamente lo que quiero obtener. Paso entonces a explicar lo que necesito y la estructura con ejemplos.

Tengo la tabla mov_factura que registra los datos de las facturas que se ingresan (es decir egresos) luego el sistema en la tabla mov_articulos registra CADA ARTICULO que interviene con la de mov_factura, es decir si una factura tiene 5 articulos distintos, se genera 1 registro en mov_factura y 5 registros en mov_articulos (haciendo referencia con la columna nro_factura que se encuentra en ambas tablas) por lo que para saber que articulos se vendieron en esa factura consultas los articulos con el nro_factura (el tipo es para saber que tipo de comprobante es, 1=factura, 2=presupuesto, etc por eso esta presente).

luego estan las tablas mov_prov_factura y mov_prov_articulos que es exactamente lo mismo pero para compras (ingresos).

Lo que necesito obtener es una rotacion de articulos y mostrear las siguientes columnas:
codigo de articulo / mombre de articulo / cantidad egresos / cantidad ingresos

Donde:
prod_cod es el codigo de articulo almacenado en mov_articulos.
prod_nom es el nombre de articulo almacenado en mov_articulos.
prod_cant es la cantidad de articulos que se vendieron en esa factura, es decir que tengo que sumar el contenido de prod_cant con todas sus coincidencias para obtener un total e ingresos o egresos agrupdo por codigo de articulo, asi mostrar solo 1 de cada uno de los articulos que intervienen en al busqueda y sumar sus totales.

Ahora explico porque relacionar la tabla mov_factura con mov_articulos:
La tabla mov_articulos contiene solo los datos del articulo y un numero de referencia de la factura (nro_factgura) pero no contiene datos relevantes a la misma, como por ejemplo: fecha, cliente, vendedor, etc.

Por eso es que necesito obtener los datos de mov_factura y filtrar con ciertos criterios y los registros de esa tabla que cumpan x condicion y luego ver los articulos en mov_articulos que corresponden a esas tablas para sumarlos. Lo mismo con la tabla de proveedores.

obviamente el sql que estoy mostrando es sin condicionales avanzadas que luego va a necesitar simplemente quiero mostrar el total efectivamente y de ahi lo empiezo a complicar segun la necesidad de los filtros.

Se entiende algo lo que puse? :/ supongo tendria que haber empezado por esto desde un principio.
  #17 (permalink)  
Antiguo 05/09/2013, 11:30
 
Fecha de Ingreso: enero-2011
Mensajes: 41
Antigüedad: 13 años, 3 meses
Puntos: 0
Respuesta: inner join con union

Agrego algo mas, con un solo par de tablas sea ventas o compras no tuve problemas en obtener los resultados con join, lo que no entiendo como hacer es la consulta a ambos pares de tabla de ventas y de compras, mostandolas combinadamente en un solo resultado.

Por lo que entiendo, el sql para obtener la sumatoria de ventas podria ser por ejemplo:
Código MySQL:
Ver original
  1. SELECT *, SUM(prod_cant) AS egresos
  2.             FROM mov_articulos
  3.             RIGHT JOIN mov_factura
  4.             ON mov_factura.id_mov_factura = mov_articulos.id_comp
  5.             WHERE mov_articulos.tipo_comp = '1'
  6.             GROUP BY prod_cod
Aqui estoy obteniendo todas las filas de articulos en mov_articulos que existan en mov_factura y esta ultima cumpla las condiciones de ser cliente 1 y tipo 1.

eso funciona perfectamente, ahora necesito conbinar el resultado con el select identico que muestra lo mismo pero del par de tablas de proveedores. asi poder tenerlos en una misma vista un resultado al lado de otro agrupado por artiuclo.

(aclaro una situacion, no se va a dar nunca la posibildad de diferir entre las tablas, siempre que exista un producto en la tabla mov_articulos tiene que haber su referente factura en al tabla mov_factura y al revez, por lo que creo que es indistinto si es right o left por ejemplo) si mal no entiendo claro esta.

En este momento hice funcionar bien el script pero no de la manera que quiero ya que tube que insertar una segunda consulta dentro del while del php que se ejecutara por cada codigo mostrado en el primer select, es esta:

Código MySQL:
Ver original
  1. SELECT *, SUM(prod_cant) AS ingresos
  2.                     FROM mov_prov_articulos
  3.                     WHERE mov_prov_articulos.tipo_comp = '1' AND mov_prov_articulos.prod_cod = '".$row['prod_cod']."'


Asi funciona, obtengo ambos datos que necesito, pero me gustaria ver si puedo hacerlo todo con un solo select, si es que se puede.


gracias por el aguante!

Última edición por freedert; 05/09/2013 a las 12:21
  #18 (permalink)  
Antiguo 06/09/2013, 05:03
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: inner join con union

freedert,
tienes que responder de algún modo al punto más importante, algo que te puso @gnzsoloyo en su última respuesta:
Cita:
Para realizar un reporte de movimiento de ingresos y egresos por productos, necesitas sí o si usar la tabla de productos, y no solamente la de movimientos, porque el que haya egresos de productos no implica necesariamente que haya ingresos del mismo producto, para el mismo período
¿No tienes una tabla productos?

La lógica general sería:
SELECT prod_cod FROM productos LEFT JOIN mov_articulos ON porprodcod LEFT JOIN mov_prov_articulos ON porprodcod

pero lo tendremos que hacer por subconsultas probablemente para controlar todo lo de las factura y demás, que eso lo resolveremos más adelante. El problema es que no existe esa tabla productos y parece que quieres hacerlo con la tabla mov_prov_articulos, que son los artículos que adquieres y guardas en almacén. Probablemente una consulta con DISTINCT de los códigos de esos artículos en mov_prov_articulos te sacará el listado de artículos del pasado y del presente, pero yo creo que lo mejor hubiera sido tener una tabla de artículos de referencia. Tal vez no te estoy entendiendo bien del todo, pero dinos si vamos muy descaminados. No puedes vender, facturar, lo que no has ingresado, eso es cierto, pero hubiera sido más fácil hacer todo desde una tabla de productos, creo. A falta de eso, esta idea para empezar a preparar:
SELECT DISTINCT prod_cod FROM mov_prov_articulos mva LEFT JOIN mov_articulos ma ON porprodcod LEFT JOIN mov_prov_articulos mva2 ON porprodcod. La idea sería esta (no he probado nada), por si te sirve de orientación:
Código MySQL:
Ver original
  1. SELECT DISTINCT mpa.prod_cod, mpa.prod_nom, T1.egresos, T2.ingresos FROM mov_prov_articulos mpa LEFT JOIN
  2.  
  3.     (SELECT mov_articulos.prod_cod, mov_articulos.prod_nom,  SUM(mov_articulos.prod_cant) AS egresos
  4.             FROM mov_articulos
  5.             INNER JOIN mov_factura
  6.             ON mov_factura.nro_factura = mov_articulos.id_comp
  7.             WHERE tipo_comp = 1
  8.             GROUP BY mov_articulos.prod_cod)T1 ON mpa.prod_cod = T1.prod_cod
  9.                    
  10.                    
  11.            LEFT JOIN (SELECT mov_prov_articulos.prod_cod, mov_prov_articulos.prod_nom, SUM(mov_prov_articulos.prod_cant) AS ingresos
  12.             FROM mov_prov_articulos
  13.             INNER JOIN mov_prov_factura
  14.             ON mov_prov_factura.nro_factura = mov_prov_articulos.id_comp
  15.             WHERE tipo_comp = 1
  16.             GROUP BY mov_prov_articulos.prod_cod)T2 ON mpa.prod_cod = T2.prod_cod GROUP BY mpa.prod_cod
  #19 (permalink)  
Antiguo 06/09/2013, 07:29
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: inner join con union

Cita:
(aclaro una situacion, no se va a dar nunca la posibildad de diferir entre las tablas, siempre que exista un producto en la tabla mov_articulos tiene que haber su referente factura en al tabla mov_factura y al revez, por lo que creo que es indistinto si es right o left por ejemplo) si mal no entiendo claro esta.
Dos cosas a destacar:
Aunque pueda parecer que "nunca" pueda existir una discrepancia entre productos de ambas tablas, eso no lo puedes garantizar jamás al 100% por una cuestión simplísima: Siempre existe la posibilidad que dado un periodo de tiempo determinado, un producto dado tenga movimientos de compra y no de venta, o de venta y no compra. Siempre ocurre.
Puede suceder, incluso, que un producto se haya comprado, y jamás se venda. Sucede...

Es más, es posible que si intentas realizar un reporte desagregado por Años, Meses, semanas, Dias y hasta horas del día, no exista plena coincidencia, puesto que incluso en una misma semana el mismo producto puede tener uno de los movimietnos y no el otro, o no tener ni uno ni otro.
Nadie que diseñe una base de datos para ventas, de ningún tipo, deja de agregar una tabla productos, porque el producto, entre otras cosas, no es un atributo de movimiento, sino que un movimiento está relacionado con un producto, y por tanto es Producto es una entidad independiente.
En otras palabras, si creaste una base de datos así, sin una tabla productos, simplemente lo has creado MAL, y conspira contra la efectividad del reporte.

Además, ¿me puedes explicar cómo sabes qué producto vender, y sus destalles descriptivos, sin tener una tabla producto?
No tenerla, implciaría consultas de demasiada complejdiad como apra ser un sistema eficiente.

Por otro lado, no es lo mismo hablar de LEFT JOIN que de RIGHT JOIN. Si las igualas es que no estás comprendiendo correctamente el sentido de ese tipo de consultas.
LEFT JOIN devuelve todo lo que está en la tabla izquierda del JOIN, tenga o no coincidencias con la derecha. Pero si aplicases a la inversa el RIGHT JOIN, sólo devolvería lo que existe en la derecha, aunque no coincida con nada de la primera tabla.
En ese contexto, como te imaginarás, realizar un LEFT JOIN o RIGHT JOIN entre los dos bloques de consultas (egreso e ingreso), pueden dar resultados erróneos.

Mi sugerencia es que si no tienes la tabla producto, la crees. A partir de allí se puede poblar con lo que ya existe.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #20 (permalink)  
Antiguo 06/09/2013, 19:46
 
Fecha de Ingreso: enero-2011
Mensajes: 41
Antigüedad: 13 años, 3 meses
Puntos: 0
Respuesta: inner join con union

Chicos chicos chicos! antes que sigan retandome, yo nunca dije que no tenia una tabla productos jaja si la hay por supuesto como en toda base de datos de ventas y compras. De echo tengo 70 tablas en este programa y muchas de esas almacenan datos estaticos como clientes, categorias, etc.

gnzsoloyo, creo que nos entendimos mal, cuando yo digo que no existe la posibilidad de discrepancia entre las tablas mov_ factura y mov_articulos me refiero a que el sistema cuando sale una venta, crea si o si un registro en ambas tablas referenciandolas, una para almacenar solamente el registro de la venta y sus datos sin los articulos (mov_factura) y otra para almacenar el numero de articulos y sus datos que intervinieron en esa venta (mov_articulos), jamas va a existir una factura en mov_facutra que no tenga articulos en mov_articulos porque el sistema no lo permite, y tampoco existirian articulos en mov_articulos que no tenga una factura por la cual fueron creados en mov_factura.

Vos me estas hablando de una discrepancia entre compra y venta, y claro que la hay! es totalmente independiente si se compra o si se venden articulos pero esto se hace en 2 pares de tablas distintas, la de mov_PROV_factura y mov_PROV_articulos son las de compra, que son iguales a las otras solo que guardan las compras unicamente y no tienen una concordancia con las de venta ni nada parecido.

Aclarado esto de la tabla productos, dicha tabla se llama articulos y guarda la informacion ademas del ID del mismo, no la uso en esta consulta porque yo no necesito recueprar nada desde esa tabla, lo unico que necesito en esta consulta en particular es el codigo y el nombre, y estos datgos asi tambien como los datos de fechas, cantidades y demas ya estan almacenados en las tablas de movimiento de factura o de articulos por lo que me parece que no necesito tocarla para nada.

En vista a que no se como explicar la estructura de mis tablas les hice un dibujito, no se rian:
https://mega.co.nz/#!ZARTRI5D!bKn4Gm...nQ4CFzxnHAonSo

por favor diganme si se entiende la estructura. no pongo mas tablas que esas porque no intervienen aca.
  #21 (permalink)  
Antiguo 07/09/2013, 04:34
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: inner join con union

Cita:
Aclarado esto de la tabla productos, dicha tabla se llama articulos y guarda la informacion ademas del ID del mismo, no la uso en esta consulta porque yo no necesito recueprar nada desde esa tabla,
Ese punto que resalto es el error conceptual que estás cometiendo...
No siempre se usan las tablas base porque se necesite recuperar algo. Se usan para facilitar el nexo entre conjuntos de datos a obtener de un modo más simple y es a eso a lo que nos referíamos.

Cita:
lo unico que necesito en esta consulta en particular es el codigo y el nombre, y estos datgos asi tambien como los datos de fechas, cantidades y demas ya estan almacenados en las tablas de movimiento de factura o de articulos por lo que me parece que no necesito tocarla para nada.
Disculpa que te lo diga,pero eso precisamente nos indica que tienes un error de diseño.
Nunca se migran atributos (datos) no primarios de una tabla base a otra tabla no base. Eso está decididamente mal, es una demostración de lo que se denomina "redundancia nociva", que puede traer como consecuencia inconsistencias en la base en algún momento.
Una de las razones de la existencia de la normalización, precisamente,es prevenir ese tipo de cosas.
Como las tablas que usas están mal creadas en ese contexto, es por eso que no terminas de ver la necesidad de la tabla base... porque estás supliéndola con desnormalización. Cosa peligrosa.


En cuanto al gráfico, por favor, usa un servicio donde puedas visualizar directamente la imagen.
Tener que aceptar los "Terminos de uso", como pide esa página, es algo que muchas veces no hacemos, por simple seguridad...
http://imageshack.us/ es una buena opción...
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #22 (permalink)  
Antiguo 07/09/2013, 05:14
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: inner join con union

Estoy totalmente de acuerdo con @gnzsoloyo. Ahora, si tú pruebas una consulta como esta en la que aparece tu tabla artículos, ¿qué te devuelve?. No he adecuado los alias, pero eso no importa en este momento tanto. Tampoco sé cómo se llama el campo nombre de artículo en la tabla artículo (yo lo he llamado nom, llamado así mpa.nom).

Código MySQL:
Ver original
  1. SELECT mpa.id, mpa.nom, T1.egresos, T2.ingresos FROM articulos mpa LEFT JOIN
  2.      
  3.         (SELECT mov_articulos.prod_cod, mov_articulos.prod_nom,  SUM(mov_articulos.prod_cant) AS egresos
  4.                 FROM mov_articulos
  5.                 INNER JOIN mov_factura
  6.                 ON mov_factura.nro_factura = mov_articulos.id_comp
  7.                 WHERE tipo_comp = 1
  8.                 GROUP BY mov_articulos.prod_cod)T1 ON mpa.id = T1.prod_cod
  9.                        
  10.                        
  11.                LEFT JOIN (SELECT mov_prov_articulos.prod_cod, mov_prov_articulos.prod_nom, SUM(mov_prov_articulos.prod_cant) AS ingresos
  12.                 FROM mov_prov_articulos
  13.                 INNER JOIN mov_prov_factura
  14.                 ON mov_prov_factura.nro_factura = mov_prov_articulos.id_comp
  15.                 WHERE tipo_comp = 1
  16.                 GROUP BY mov_prov_articulos.prod_cod)T2 ON mpa.id= T2.prod_cod GROUP BY mpa.id

Última edición por jurena; 07/09/2013 a las 09:11

Etiquetas: join, php, select, tabla, union
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 02:20.