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

Compras y Ventas en la misma consulta

Estas en el tema de Compras y Ventas en la misma consulta en el foro de Mysql en Foros del Web. Tengo estas tablas. articulo claart (clave primaria) nombre (varchar) venta id_venta (clave primaria) claart (indice) precio (float) cantidad (int) fecha (date) empresa claemp (clave primaria) ...
  #1 (permalink)  
Antiguo 16/01/2013, 06:27
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Compras y Ventas en la misma consulta

Tengo estas tablas.
articulo
claart (clave primaria)
nombre (varchar)

venta
id_venta (clave primaria)
claart (indice)
precio (float)
cantidad (int)
fecha (date)

empresa
claemp (clave primaria)
nomemp (varchar)

Y también la de compras que es exactamente igual a la de venta.

Tengo esta consulta para sacar las ventas y verlo por mes:
Código MySQL:
Ver original
  1. SELECT a.codigo, a.nombre,
  2.                 ROUND(AVG(v.precio), 2) 'Media Ventas',
  3.                 SUM(IF(month(v.fecha)=1, v.cantidad, 0)) 'Enero',
  4.                 SUM(IF(month(v.fecha)=2, v.cantidad, 0)) 'Febrero',
  5.                 SUM(IF(month(v.fecha)=3, v.cantidad, 0)) 'Marzo',
  6.                 SUM(IF(month(v.fecha)=4, v.cantidad, 0)) 'Abril',
  7.                 SUM(IF(month(v.fecha)=5, v.cantidad, 0)) 'Mayo',
  8.                 SUM(IF(month(v.fecha)=6, v.cantidad, 0)) 'Junio',
  9.                 SUM(IF(month(v.fecha)=7, v.cantidad, 0)) 'Julio',
  10.                 SUM(IF(month(v.fecha)=8, v.cantidad, 0)) 'Agosto',
  11.                 SUM(IF(month(v.fecha)=9, v.cantidad, 0)) 'Septiembre',
  12.                 SUM(IF(month(v.fecha)=10, v.cantidad, 0)) 'Octubre',
  13.                 SUM(IF(month(v.fecha)=11, v.cantidad, 0)) 'Noviembre',
  14.                 SUM(IF(month(v.fecha)=12, v.cantidad, 0)) 'Diciembre',
  15.                 SUM(v.cantidad) 'Total Ventas'
  16.                 FROM articulo a INNER JOIN venta v ON a.claart = v.claart
  17.                 WHERE year(fecha)=2012
  18.                 GROUP BY codigo

Pero además quería añadir las compras en la misma consulta si es que hay alguna forma y no lo consigo. O la base de datos se queda congelada un rato hasta que me dice que que el SQL "Has gone away" o me da error.

Las compras son lo mismo cambiando la tabla venta por compra. Exactamente igual.

Y para rizar más el rizo ademas estas compras y ventas tienen una "claemp" (clave empresa) y aunque serían muchísimas columnas para comparar datos sería mucho más cómodo así que tendría que quedar algo así como:

claart | Media precio Compras | Compras Enero Empresa A | Compras Enero Empresa B

¿Es esto viable o es pedir demasiado a la bd?

Última edición por gnzsoloyo; 16/01/2013 a las 06:46
  #2 (permalink)  
Antiguo 16/01/2013, 07:56
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Compras y Ventas en la misma consulta

Código MySQL:
Ver original
  1. SELECT sbc.codigo, sbc.nombre,
  2.                 ROUND(AVG(sbc.precioVenta), 2) 'Media Ventas',
  3.                 ROUND(AVG(sbc.precioCompra), 2) 'Media Compras',
  4.                 SUM(IF(MONTH(v.fecha)=1, sbc.CantidadVentas, 0)) 'EneroV',
  5.                 SUM(IF(MONTH(v.fecha)=1, sbc.CantidadCompras, 0)) 'EneroC',
  6.                 SUM(IF(MONTH(v.fecha)=2, sbc.CantidadVentas, 0)) 'FebreroV',
  7.                 SUM(IF(MONTH(v.fecha)=2, sbc.CantidadCompras, 0)) 'FebreroC',
  8.                 SUM(IF(MONTH(v.fecha)=3, sbc.CantidadVentas, 0)) 'MarzoV',
  9.                 SUM(IF(MONTH(v.fecha)=3, sbc.CantidadCompras, 0)) 'MarzoC',
  10.                 SUM(IF(MONTH(v.fecha)=4, sbc.CantidadVentas, 0)) 'AbrilV',
  11.                 SUM(IF(MONTH(v.fecha)=4, sbc.CantidadCompras, 0)) 'AbrilC',
  12.                 SUM(IF(MONTH(v.fecha)=5, sbc.CantidadVentas, 0)) 'MayoV',
  13.                 SUM(IF(MONTH(v.fecha)=5, sbc.CantidadCompras, 0)) 'MayoC',
  14.                 SUM(IF(MONTH(v.fecha)=6, sbc.CantidadVentas, 0)) 'JunioV',
  15.                 SUM(IF(MONTH(v.fecha)=6, sbc.CantidadCompras, 0)) 'JunioC',
  16.                 SUM(IF(MONTH(v.fecha)=7, sbc.CantidadVentas, 0)) 'JulioV',
  17.                 SUM(IF(MONTH(v.fecha)=7, sbc.CantidadCompras, 0)) 'JulioC',
  18.                 SUM(IF(MONTH(v.fecha)=8, sbc.CantidadVentas, 0)) 'AgostoV',
  19.                 SUM(IF(MONTH(v.fecha)=8, sbc.CantidadCompras, 0)) 'AgostoC',
  20.                 SUM(IF(MONTH(v.fecha)=9, sbc.CantidadVentas, 0)) 'SeptiembreV',
  21.                 SUM(IF(MONTH(v.fecha)=9, sbc.CantidadCompras, 0)) 'SeptiembreC',
  22.                 SUM(IF(MONTH(v.fecha)=10, sbc.CantidadVentas, 0)) 'OctubreV',
  23.                 SUM(IF(MONTH(v.fecha)=10, sbc.CantidadCompras, 0)) 'OctubreC',
  24.                 SUM(IF(MONTH(v.fecha)=11, sbc.CantidadVentas, 0)) 'NoviembreV',
  25.                 SUM(IF(MONTH(v.fecha)=11, sbc.CantidadCompras, 0)) 'NoviembreC',
  26.                 SUM(IF(MONTH(v.fecha)=12, sbc.CantidadVentas, 0)) 'DiciembreV',
  27.                 SUM(IF(MONTH(v.fecha)=12, sbc.CantidadCompras, 0)) 'DiciembreC',
  28.                 SUM(sbc.CantidadVentas) 'Total Compras'
  29.                 SUM(sbc.CantidadCompras) 'Total Compras'
  30. SELECT a1.codigo, a1.nombre,
  31.              c.precio precioCompra,
  32.              null as precioVenta,
  33.              c.fecha,
  34.              c.cantidad as "CatidadCompras",
  35.              0 as "CantidadVentas"
  36. FROM articulo a1 INNER JOIN compras c ON a1.claart = c.claart
  37. WHERE YEAR(c.fecha)=2012
  38. SELECT a2.codigo, a2.nombre,
  39.              null as precioCompra,
  40.              v.precio as precioVenta,
  41.              v.fecha,
  42.              0 as "CatidadCompras",
  43.              v.cantidad as "CantidadVentas"
  44. FROM articulo a2 INNER JOIN ventas v ON a2.claart = v.claart
  45. WHERE YEAR(v.fecha)=2012) as Sbc
  46. GROUP BY sbc.codigo;

Algo así?

Mira si hace bien el precio medio.... ojo con el precio medio calculado así ....imagina esta situación



Op.......Precio.....Cantidad
Compra...1...........1
Compra...100.........100
Venta....100.........1
Venta....1...........100


Todo del mismo producto

Precio medio de venta (100+1)/2=50,5
Precio medio de compra (100+1)/2=50,5

Beneficio 0 (Cero)???????

Cuando en realidad estas perdindo vacas y cencerros.

Gastos (1x1)+(100x100)=10001
Ingresos (1x100)+(100x1)=200


Benficio 200-10001=-9801 (negativo)
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.

Última edición por quimfv; 16/01/2013 a las 08:14
  #3 (permalink)  
Antiguo 16/01/2013, 09:27
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Respuesta: Compras y Ventas en la misma consulta

Muchisimas gracias Quim. Sobretodo por la explicación de las medias. Voy a ver si me está dando bien.

Me daba algunos errores como los nombres de las tablas, ventas por venta y poco más, los arreglé, y ahora me dice.

No se encuentra v.fecha

Aquí con las pequeñas correcciones:
Código MySQL:
Ver original
  1. SELECT sbc.codigo, sbc.nombre,
  2.                 ROUND(AVG(sbc.precioVenta), 2) 'Media Ventas',
  3.                 ROUND(AVG(sbc.precioCompra), 2) 'Media Compras',
  4.                 SUM(IF(MONTH(v.fecha)=1, sbc.CantidadVentas, 0)) 'EneroV',
  5.                 SUM(IF(MONTH(v.fecha)=1, sbc.CantidadCompras, 0)) 'EneroC',
  6.                 SUM(IF(MONTH(v.fecha)=2, sbc.CantidadVentas, 0)) 'FebreroV',
  7.                 SUM(IF(MONTH(v.fecha)=2, sbc.CantidadCompras, 0)) 'FebreroC',
  8.                 SUM(IF(MONTH(v.fecha)=3, sbc.CantidadVentas, 0)) 'MarzoV',
  9.                 SUM(IF(MONTH(v.fecha)=3, sbc.CantidadCompras, 0)) 'MarzoC',
  10.                 SUM(IF(MONTH(v.fecha)=4, sbc.CantidadVentas, 0)) 'AbrilV',
  11.                 SUM(IF(MONTH(v.fecha)=4, sbc.CantidadCompras, 0)) 'AbrilC',
  12.                 SUM(IF(MONTH(v.fecha)=5, sbc.CantidadVentas, 0)) 'MayoV',
  13.                 SUM(IF(MONTH(v.fecha)=5, sbc.CantidadCompras, 0)) 'MayoC',
  14.                 SUM(IF(MONTH(v.fecha)=6, sbc.CantidadVentas, 0)) 'JunioV',
  15.                 SUM(IF(MONTH(v.fecha)=6, sbc.CantidadCompras, 0)) 'JunioC',
  16.                 SUM(IF(MONTH(v.fecha)=7, sbc.CantidadVentas, 0)) 'JulioV',
  17.                 SUM(IF(MONTH(v.fecha)=7, sbc.CantidadCompras, 0)) 'JulioC',
  18.                 SUM(IF(MONTH(v.fecha)=8, sbc.CantidadVentas, 0)) 'AgostoV',
  19.                 SUM(IF(MONTH(v.fecha)=8, sbc.CantidadCompras, 0)) 'AgostoC',
  20.                 SUM(IF(MONTH(v.fecha)=9, sbc.CantidadVentas, 0)) 'SeptiembreV',
  21.                 SUM(IF(MONTH(v.fecha)=9, sbc.CantidadCompras, 0)) 'SeptiembreC',
  22.                 SUM(IF(MONTH(v.fecha)=10, sbc.CantidadVentas, 0)) 'OctubreV',
  23.                 SUM(IF(MONTH(v.fecha)=10, sbc.CantidadCompras, 0)) 'OctubreC',
  24.                 SUM(IF(MONTH(v.fecha)=11, sbc.CantidadVentas, 0)) 'NoviembreV',
  25.                 SUM(IF(MONTH(v.fecha)=11, sbc.CantidadCompras, 0)) 'NoviembreC',
  26.                 SUM(IF(MONTH(v.fecha)=12, sbc.CantidadVentas, 0)) 'DiciembreV',
  27.                 SUM(IF(MONTH(v.fecha)=12, sbc.CantidadCompras, 0)) 'DiciembreC',
  28.                 SUM(sbc.CantidadVentas) 'Total Ventas',
  29.                 SUM(sbc.CantidadCompras) 'Total Compras'
  30. SELECT a1.codigo, a1.nombre,
  31.              c.precio precioCompra,
  32.              NULL as precioVenta,
  33.              c.fecha,
  34.              c.cantidad as "CantidadCompras",
  35.              0 as "CantidadVentas"
  36. FROM articulo a1 INNER JOIN compra c ON a1.claart = c.claart
  37. WHERE YEAR(c.fecha)=2012
  38. SELECT a2.codigo, a2.nombre,
  39.              NULL as precioCompra,
  40.              v.precio as precioVenta,
  41.              v.fecha,
  42.              0 as "CantidadCompras",
  43.              v.cantidad as "CantidadVentas"
  44. FROM articulo a2 INNER JOIN venta v ON a2.claart = v.claart
  45. WHERE YEAR(v.fecha)=2012) as Sbc
  46. GROUP BY sbc.codigo

No veo el problema la verdad porque la consulta me parece complejísima y no entiendo ya lo de FROM (consultas varias)

Efectivamente así me da mal la media tal y como tú decías ya que la cantidad no entra en juego.

Última edición por alyciashape; 16/01/2013 a las 09:47
  #4 (permalink)  
Antiguo 17/01/2013, 01:51
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Compras y Ventas en la misma consulta

Código MySQL:
Ver original
  1. SELECT sbc.codigo, sbc.nombre,
  2.                 ROUND(AVG(sbc.precioVenta), 2) 'Media Ventas',
  3.                 ROUND(AVG(sbc.precioCompra), 2) 'Media Compras',
  4.                 SUM(IF(MONTH(sbc.fecha)=1, sbc.CantidadVentas, 0)) 'EneroV',
  5.                 SUM(IF(MONTH(sbc.fecha)=1, sbc.CantidadCompras, 0)) 'EneroC',
  6.                 SUM(IF(MONTH(sbc.fecha)=2, sbc.CantidadVentas, 0)) 'FebreroV',
  7.                 SUM(IF(MONTH(sbc.fecha)=2, sbc.CantidadCompras, 0)) 'FebreroC',
  8.                 SUM(IF(MONTH(sbc.fecha)=3, sbc.CantidadVentas, 0)) 'MarzoV',
  9.                 SUM(IF(MONTH(sbc.fecha)=3, sbc.CantidadCompras, 0)) 'MarzoC',
  10.                 SUM(IF(MONTH(sbc.fecha)=4, sbc.CantidadVentas, 0)) 'AbrilV',
  11.                 SUM(IF(MONTH(sbc.fecha)=4, sbc.CantidadCompras, 0)) 'AbrilC',
  12.                 SUM(IF(MONTH(sbc.fecha)=5, sbc.CantidadVentas, 0)) 'MayoV',
  13.                 SUM(IF(MONTH(sbc.fecha)=5, sbc.CantidadCompras, 0)) 'MayoC',
  14.                 SUM(IF(MONTH(sbc.fecha)=6, sbc.CantidadVentas, 0)) 'JunioV',
  15.                 SUM(IF(MONTH(sbc.fecha)=6, sbc.CantidadCompras, 0)) 'JunioC',
  16.                 SUM(IF(MONTH(sbc.fecha)=7, sbc.CantidadVentas, 0)) 'JulioV',
  17.                 SUM(IF(MONTH(sbc.fecha)=7, sbc.CantidadCompras, 0)) 'JulioC',
  18.                 SUM(IF(MONTH(sbc.fecha)=8, sbc.CantidadVentas, 0)) 'AgostoV',
  19.                 SUM(IF(MONTH(sbc.fecha)=8, sbc.CantidadCompras, 0)) 'AgostoC',
  20.                 SUM(IF(MONTH(sbc.fecha)=9, sbc.CantidadVentas, 0)) 'SeptiembreV',
  21.                 SUM(IF(MONTH(sbc.fecha)=9, sbc.CantidadCompras, 0)) 'SeptiembreC',
  22.                 SUM(IF(MONTH(sbc.fecha)=10, sbc.CantidadVentas, 0)) 'OctubreV',
  23.                 SUM(IF(MONTH(sbc.fecha)=10, sbc.CantidadCompras, 0)) 'OctubreC',
  24.                 SUM(IF(MONTH(sbc.fecha)=11, sbc.CantidadVentas, 0)) 'NoviembreV',
  25.                 SUM(IF(MONTH(sbc.fecha)=11, sbc.CantidadCompras, 0)) 'NoviembreC',
  26.                 SUM(IF(MONTH(sbc.fecha)=12, sbc.CantidadVentas, 0)) 'DiciembreV',
  27.                 SUM(IF(MONTH(sbc.fecha)=12, sbc.CantidadCompras, 0)) 'DiciembreC',
  28.                 SUM(sbc.CantidadVentas) 'Total Ventas',
  29.                 SUM(sbc.CantidadCompras) 'Total Compras'
  30. SELECT a1.codigo, a1.nombre,
  31.              c.precio precioCompra,
  32.              NULL as precioVenta,
  33.              c.fecha,
  34.              c.cantidad as "CantidadCompras",
  35.              0 as "CantidadVentas"
  36. FROM articulo a1 INNER JOIN compra c ON a1.claart = c.claart
  37. WHERE YEAR(c.fecha)=2012
  38. SELECT a2.codigo, a2.nombre,
  39.              NULL as precioCompra,
  40.              v.precio as precioVenta,
  41.              v.fecha,
  42.              0 as "CantidadCompras",
  43.              v.cantidad as "CantidadVentas"
  44. FROM articulo a2 INNER JOIN venta v ON a2.claart = v.claart
  45. WHERE YEAR(v.fecha)=2012) as sbc
  46. GROUP BY sbc.codigo

No es compleja es una consulta sobre una subconsulta (sbc) que a su vez es una union de consultas.

SELECT .... FROM (SELECT... UNION ALL SELECT...) as sbc WHERE... GROUP BY....

Ahora funcionará....he cambiado v.fecha por sbc.fecha en el primer select ....

El precio medio debe ser ponderado.... SUMA(precio*cantidad)/SUMA(cantidad).


Código MySQL:
Ver original
  1. SELECT a1.codigo, a1.nombre,
  2.              SUM(c.precio*c.cantidad)/SUM(c.cantidad) PrecioMedioCompras
  3. FROM articulo a1 INNER JOIN compra c ON a1.claart = c.claart
  4. WHERE YEAR(c.fecha)=2012
  5. GROUP BY c.codigo
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.

Última edición por quimfv; 17/01/2013 a las 02:07
  #5 (permalink)  
Antiguo 17/01/2013, 03:12
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Respuesta: Compras y Ventas en la misma consulta

Muchísimas gracias Quim, ahora si que funciona. Y además he entendido lo del FROM cosa que no sabía usar solo con ese pequeño comentario que añadiste.

Esto equivale a hacer una vista y hacer una consulta a esa vista no? lo de SELECT campos FROM (SELECT campos). El rendimiento sería similar o compensa hacer una vista?
  #6 (permalink)  
Antiguo 17/01/2013, 05:23
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Respuesta: Compras y Ventas en la misma consulta

No quería abusar pero pensando en lo de FROM () estaba pensando si esto podría funcionar? Es sólo una prueba:

Probablemente sea un disparate ya que ni lo he probado que no estoy en casa. Son 2 tablas idénticas. Compras y ventas. Si solo quisiera saber la diferencia de compras-ventas podría hacer algo así?

Código MySQL:
Ver original
  1. SELECT claart, SUM(cantidad) 'cantidad' FROM (
  2. SELECT claart, claemp, SUM(cantidad) 'cantidad'
  3. FROM compra WHERE year(fecha)<2011
  4. SELECT claart, claemp, SUM(cantidad) 'cantidad'
  5. FROM venta WHERE year(fecha)<2011
  6. )
  #7 (permalink)  
Antiguo 17/01/2013, 06:52
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Compras y Ventas en la misma consulta

Código MySQL:
Ver original
  1. SELECT claart, SUM(sbc.cantidadC),
  2.                         SUM(sbc.cantidadV),  
  3.                         SUM(sbc.cantidadC)-SUM(sbc.cantidadV) 'Saldo'
  4. SELECT claart, claemp, cantidad 'cantidadC',0  'cantidadV'
  5. FROM compra WHERE year(fecha)<2011
  6. SELECT claart, claemp, 0  'cantidadC', cantidad 'cantidadV'
  7. FROM venta WHERE year(fecha)<2011
  8. ) as sbc
  9. GROUP BY claart;

Si hay mas de un claemp por cada claart deberias agregarlo al group by....

Cita:
Esto equivale a hacer una vista y hacer una consulta a esa vista no? lo de SELECT campos FROM (SELECT campos). El rendimiento sería similar o compensa hacer una vista?
Equivalente del todo no pero es similar....

Una vista es una consulta guardada por decirlo de alguna manera, es eficiente si esa consulta la vas a usar habitualmente... si no hay diferencia... en mysql el uso forzado de indices que se puede hacer en una consulta para mejorar el rendimiento, no se puede usar en una vista... almenos hasta las versiones que he tocado... no se si ha cambiado.
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.

Última edición por quimfv; 17/01/2013 a las 06:57

Etiquetas: compras, select, sql, tabla, ventas
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 12:03.