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

SUM y JOIN

Estas en el tema de SUM y JOIN en el foro de Mysql en Foros del Web. Hola, queria sumar varias cosas de golpe. Pero al hacer la suma, no se porque no sale bien, he probado tambien a poner dos where ...
  #1 (permalink)  
Antiguo 09/11/2009, 14:34
 
Fecha de Ingreso: mayo-2005
Mensajes: 51
Antigüedad: 19 años, 6 meses
Puntos: 0
SUM y JOIN

Hola, queria sumar varias cosas de golpe. Pero al hacer la suma, no se porque no sale bien, he probado tambien a poner dos where para cada tabla. Pero aun asi no sale lo que deberia, haciendo un sum con una tabla, si que sale bien.

Código sql:
Ver original
  1. SELECT SUM( pos_loc_tpv.cta ) AS cta, SUM( pos_loc_cln.total ) AS Total,
  2.  COUNT( pos_loc_tpv.vid ) AS Vid,
  3. COUNT( pos_loc_cln.clid ) AS Cliente
  4. FROM pos_loc_cln
  5. INNER JOIN pos_loc_tpv ON pos_loc_tpv.fecha = pos_loc_cln.fch
  6. WHERE pos_loc_cln.fch = '2009-11-09'
  7. AND pos_loc_tpc.dev = '0'

Si alguien me puede decir que es lo que estoy haciendo mal, se lo agradeceria, gracias.

Pd: La version de mysql es 5.0.51a-3ubuntu5.4 (Ubuntu)

+++EDIT: He añadido el 'AND pos_loc_tpv.dev='0''+++

salu2

Última edición por finord; 09/11/2009 a las 17:52
  #2 (permalink)  
Antiguo 09/11/2009, 14:37
Avatar de Vun
Vun
Colaborador
 
Fecha de Ingreso: agosto-2009
Ubicación: Benalmádena, España
Mensajes: 2.265
Antigüedad: 15 años, 3 meses
Puntos: 150
Respuesta: SUM y JOIN

Aqui no hay adivinos!!!!

Escribe que tablas tienes, que campos tienes, varios registros de ejemplo y lo quieres conseguir, y asi te van a ayudar mas facilmente en vez de ignorar tu post
  #3 (permalink)  
Antiguo 09/11/2009, 14: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: 17 años
Puntos: 2658
Respuesta: SUM y JOIN

Cita:
queria sumar varias cosas de golpe. Pero al hacer la suma, no se porque no sale bien,
Supongamos que quieres decir que deseas realizar la suma en una sola consulta, al mismo tiempo que cuentas la cantidad de instancias sumadas.
eso sería lo que haces al realizar:
Código:
SELECT 
     sum( pos_loc_tpv.cta ) AS cta, 
     sum( pos_loc_cln.total ) AS Total,
     count( pos_loc_tpv.dev ) AS Dev, 
     count( pos_loc_tpv.vid ) AS Vid,
     count( pos_loc_cln.clid ) AS Cliente
FROM pos_loc_cln INNER JOIN pos_loc_tpv 
     ON pos_loc_tpv.fecha = pos_loc_cln.fch
WHERE pos_loc_cln.fch = '2009-11-09';
Hasta allí, no hay errores, por lo que las sumas y las cuentas deberían realizarse. Si no te salen los valores esperados, es porque no estás planteando correctamente todos los elementos de la consulta.

Dinos qué es lo que debes sumar y cómo quieres agrupar los resultados.

Cita:
he probado tambien a poner dos where para cada tabla
Este comentario nos muestra que no estás familiarizado con el SQL: Una sentencia DML solo puede llevar UN WHERE; el resto es manejo de operadores lógicos y paréntesis.
Si pones dos WHERE solo conseguirás un error.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #4 (permalink)  
Antiguo 09/11/2009, 17:37
 
Fecha de Ingreso: mayo-2005
Mensajes: 51
Antigüedad: 19 años, 6 meses
Puntos: 0
Respuesta: SUM y JOIN

Hola, aqui esta la estructura de las tablas. No la puse antes, porque creia que el fallo estaba en el join que hice yo.

Código sql:
Ver original
  1. CREATE TABLE IF NOT EXISTS `pos_loc_cln` (
  2.   `clid` INT(11) NOT NULL AUTO_INCREMENT,
  3.   `fch` DATE NOT NULL,
  4.   `hor` TIME NOT NULL,
  5.   `hash` VARCHAR(255) NOT NULL,
  6.   `local` VARCHAR(115) NOT NULL,
  7.   `est` VARCHAR(255) NOT NULL,
  8.   `total` VARCHAR(255) NOT NULL,
  9.   `entrada` VARCHAR(255) NOT NULL,
  10.   `vuelta` VARCHAR(255) NOT NULL,
  11.   `cr_hor` TIME NOT NULL,
  12.   `ttop` VARCHAR(255) NOT NULL,
  13.   `tst` datetime NOT NULL,
  14.   `ts2` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  15.   PRIMARY KEY  (`clid`),
  16.   UNIQUE KEY `key` (`hash`)
  17. ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=26 ;
  18.  
  19. -- --------------------------------------------------------
  20.  
  21. --
  22. -- Estructura de tabla para la tabla `pos_loc_tpv`
  23. --
  24.  
  25. CREATE TABLE IF NOT EXISTS `pos_loc_tpv` (
  26.   `vid` INT(11) NOT NULL AUTO_INCREMENT,
  27.   `pid` INT(255) NOT NULL,
  28.   `pnotes` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  29.   `fecha` DATE NOT NULL,
  30.   `pcat` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
  31.   `prc` VARCHAR(255) NOT NULL,
  32.   `hora` TIME NOT NULL,
  33.   `opst` INT(11) NOT NULL,
  34.   `cta` VARCHAR(255) NOT NULL,
  35.   `nom` VARCHAR(255) NOT NULL,
  36.   `clid` INT(11) NOT NULL,
  37.   `local` VARCHAR(255) NOT NULL,
  38.   `dev` INT(11) NOT NULL,
  39.   `dvid` VARCHAR(255) NOT NULL,
  40.   `dpid` VARCHAR(255) NOT NULL,
  41.   `did` INT(11) NOT NULL,
  42.   `drid` VARCHAR(255) NOT NULL,
  43.   `key` VARCHAR(255) NOT NULL,
  44.   `octa` VARCHAR(255) NOT NULL,
  45.   `edid` INT(11) NOT NULL,
  46.   `dprc` INT(11) NOT NULL,
  47.   `dcta` INT(11) NOT NULL,
  48.   PRIMARY KEY  (`vid`)
  49. ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=99 ;


Ejecutando esta consulta
Código sql:
Ver original
  1. SELECT SUM( cta ) , SUM( prc ) , COUNT( vid )
  2. FROM `pos_loc_tpv`
  3. WHERE fecha = '2009-11-08'

Me devuelve:
Código sql:
Ver original
  1. SUM(cta)    SUM(prc)    COUNT(vid)
  2. 32               20.8                     27

gnzsoloyo, he probado lo que me has puesto y da el mismo resultado. Sobre lo del where, cuando dije que puse dos where, me referia a que use where ... and .. (como la q aparece aqui), fallo mio por no ponerlo bien.

LA idea es sumar la cantidad de productos vendidos(cta) y que concuerden con las cantidades que devuelve pos_loc_cln.total. Y contar el numero de operaciones (vid) y clientes que se hayan producido ese dia, y donde el valor de dev sea igual a 0.

No se porque me salen un valores tan error, de hecho, suamdno todos los valores de de pos_loc_tpv.cta, sin tener en cuenta la fecha, me sale unos 100, mientras que con el JOIN me sale 300.

pd: he quitado el contar dev, porque no hay forma de contarlo sin que afecte a los demas.

Gracias

Última edición por finord; 09/11/2009 a las 17:51
  #5 (permalink)  
Antiguo 09/11/2009, 20:09
Avatar de Vun
Vun
Colaborador
 
Fecha de Ingreso: agosto-2009
Ubicación: Benalmádena, España
Mensajes: 2.265
Antigüedad: 15 años, 3 meses
Puntos: 150
Respuesta: SUM y JOIN

Entonces lo que te ocurre es que no te cuadran los valores........

SELECT sum( cta ) , sum( prc ) , count( vid )
FROM `pos_loc_tpv`
WHERE fecha = '2009-11-08'


Fijate tu manualmente en los 27 registros y sumalos, luego analiza porque no te da igual que la otra cantidad, a ver si va a estar mal el total ese.....
  #6 (permalink)  
Antiguo 09/11/2009, 20:38
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: SUM y JOIN

Viendo las tablas, el primer problema que se pone en evidencia es que la fecha no puede ser una clave de relación entre ambas. Eso está produciendo un resultado falso, por cuanto no hay una correspondencia 1:1 entre los campos de fecha de ambas tablas.
para que el JOIN tenga algún sentido, debe haber una correspondencia entre ambas tablas, y que no es la que se está usando.
Me gustaría que nos dijeses qué tipo de información guarda cada tabla, porque por los nombres no me resulta claro, y tampoco me resulta clara la relación que hay entre ambas. Está demasiado codificada.
__________________
¿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 10/11/2009, 05:39
 
Fecha de Ingreso: mayo-2005
Mensajes: 51
Antigüedad: 19 años, 6 meses
Puntos: 0
Respuesta: SUM y JOIN

Hola, el funcionamiento viene a ser el siguiente:
(pos_loc_cln-->X, pos_loc_tpv->Y)

1ºX se crear cuando hay un nuevo cliente, con un identificador de cliente (clid).
2º- Cada vez que se registra una venta, se inserta en Y con el 'clid' creado antes, asi sucesivamente.
3ºAl cerrar el cliente, la suma de productos vendidos(cta) y el valor de las ventas(prc), se inserta el X.
4º (Que es lo que intento hacer) Al terminar el dia, contar el numero de clientes creados, su valor de ventas, el numero de operaciones.

Porque no sirve la fecha como valor de concordancia?, porque se crean en el mismo dia, y tiene la misma fecha.

salu2 y gracias.
  #8 (permalink)  
Antiguo 10/11/2009, 06:02
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: SUM y JOIN

Cita:
Porque no sirve la fecha como valor de concordancia?, porque se crean en el mismo dia, y tiene la misma fecha.
Porque si el mismo día se crearon el cliente 14,15,, 16, 17, 18, y 19, lo que tendrás al cruzar los campos fecha es
Cita:
Cliente14 - DatosCliente14
Cliente14 - DatosCliente15
Cliente14 - DatosCliente16
Cliente14 - DatosCliente17
Cliente14 - DatosCliente18
Cliente14 - DatosCliente19
Cliente15 - DatosCliente14
Cliente15 - DatosCliente15
Cliente15 - DatosCliente16
Cliente15 - DatosCliente17
Cliente15 - DatosCliente18
Cliente15 - DatosCliente19
...
... y así hasta llegar al Cliente19
Y esto porque el campo tiene el mismo valor en todos los casos. Es lo que se denomina "producto cartesiano". Para evitarlo hay que lograr que la relación sea 1:1, o bien replantear la lógica de la consulta, ya que lo que estás pidiendo aquí:
Código sql:
Ver original
  1. SELECT
  2.     SUM( pos_loc_tpv.cta ) AS cta,
  3.     SUM( pos_loc_cln.total ) AS Total,
  4.     COUNT( pos_loc_tpv.vid ) AS Vid,
  5.     COUNT( pos_loc_cln.clid ) AS Cliente
  6. FROM pos_loc_cln
  7. INNER JOIN pos_loc_tpv ON pos_loc_tpv.fecha = pos_loc_cln.fch
  8. WHERE pos_loc_cln.fch = '2009-11-09'
  9. AND pos_loc_tpc.dev = '0'
No es lo que dices buscar...
Dos preguntas:
1) Si la tabla que administra los clientes creados, es pos_loc_cln, ¿Por qué los datos personales están en pos_loc_tpv, donde se supone que estarían las ventas.
2) ¿Por qué almacenas dos datos que son calculables por consulta en una tabla primaria como es pos_loc_cln? No es eficiente y requiere un acceso a disco innecesario...

Yendo al problema, si la venta y la cantidad correspondientes a un día están en una sola tabla, la otra es innecesaria:
Código sql:
Ver original
  1. SELECT
  2.   SUM(`TotalVenta`) Venta,
  3.   SUM(`TotalProductos`) Productos,
  4.   COUNT(*) SumaClientes
  5. FROM
  6.   (SELECT
  7.       SUM(T.dcta ) AS `TotalVenta`,
  8.       SUM(T.dprc) AS `TotalProductos`,
  9.       T.clid AS Clientes
  10.   FROM pos_loc_tpv T
  11.   WHERE T.fecha = '2009-11-09' AND T.dev = '0'
  12.   GROUP BY Clientes) T1;
Se requiere que sea una subconsulta para que no cuente dos veces clientes que puedan haber hecho dos compras el mismo día.
__________________
¿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 14/11/2009, 08:21
 
Fecha de Ingreso: mayo-2005
Mensajes: 51
Antigüedad: 19 años, 6 meses
Puntos: 0
Respuesta: SUM y JOIN

Hola, perona por no haber respondido, que he estado muy liado.

Ahora ya veo donde esta el problema,1:1 no lo habia entendido de manera correcta -_-

Sobre las pregunas:
1) Necesito que cada venta se realice de forma individual, para cancelarlos llegado el momento.
LA cuestion de hacerlo asi, es que la aplicaicon esta enfocado a usar en una tienda, y se hacen muy rapido. La entrada de daos es por un lector. Cada venta se registra con un insert, y si se cancela la venta, se actualiza con cantidad y precio 0, ademas de crear otro registro de la cancelacion de la venta.
He usado un sistema parecido a la filosofia que se usa en contabilidad, todas las acciones estan registradas y no se borra nada, solo se anula con otro registro.

Tambien hay que decir, aunue creo q ya se nota, que no soy un profesional ni nada (de hecho los locales son mios), lo estoy haciendo con lo que he aprendido por curiosidad (usando php, jquery y mysql), y en el lugar de adaptarnos a un aplicacion o depender de alguien cada vez que cambiemos alguna cosa, he decidod hacerlo yo mismo, y adaptar la aplicacion a lo que nos haga falta.

2) Aqui tiene razon, voy a hacer una sola consulta a pos_loc_cln. La idea de hacer dos era comprobar que la cantidad que aparece en el registro de ventas se corresponden con la que aparece en clientes. De todos modos, mirare otra forma de probarlo.

Y sobre el codigo que me has puesto, no me devuelve nada.

De todos modos, hacer una consula de esa manera, es como realizar dos peticiones de manera independiente, o es como si fuera una sola? Me refiero desde el punto de vista del rendimiento.


salu2 y gracias.

Última edición por finord; 14/11/2009 a las 09:07
  #10 (permalink)  
Antiguo 15/11/2009, 07:42
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: SUM y JOIN

Cita:
Necesito que cada venta se realice de forma individual, para cancelarlos llegado el momento.
LA cuestion de hacerlo asi, es que la aplicaicon esta enfocado a usar en una tienda, y se hacen muy rapido. La entrada de daos es por un lector. Cada venta se registra con un insert, y si se cancela la venta, se actualiza con cantidad y precio 0, ademas de crear otro registro de la cancelacion de la venta.
He usado un sistema parecido a la filosofia que se usa en contabilidad, todas las acciones estan registradas y no se borra nada, solo se anula con otro registro.
Bueno, ahora es un poco más claro de dónde vienen algunos detalles poco convencionales. En definitiva ha sido por la diferencia entre la visión de usuario, experimentado en contabilidad, más cercano a la programación, y la visión de los DBA que se orienta a un paradigma diferente.

En esencia, el funcionamiento de un sistema de ventas como el que describes requiere como mínimo de cuatro tablas, y puede que algunas más dependiendo de algunos detalles.

En ejemplo de cómo sería un diseño aplicable a facturación sería:


En ese contexto, cuando iniciaras una venta lo que se hace es dar de alta la venta en la tabla Factura, tras lo que recuperas el ID. Este ID se usa como parte del insert de los diferentes items de venta, todos los cuales llevan el ID del producto, que en tu caso debería ser el código leído por el lector de barras.
El cierre de la venta y la cancelación de la cuenta se producen entonces con el ingreso del Cobro, que refiere por FK a la factura. La cancelación de un ítem o la cancelación de la misma factura, puede bien seguir la misma lógica que tu planteas.
Obviamente, este modelo requiere la existencia de clientes ya dados de alta, pero eso mismo se podría resolver usando tanto los medios de pago (tarjetas, por ejemplo), como alta directa. El problema sería resolver la asignación de la venta si las facturas no llevan ID de cliente, caso en el que se podría pensar en un cliente anónimo, con un ID específico.

Para poder un realizar un modelo más cercano a lo que tu usas debería conocer cuáles son las reglas del negocio que aplicas para el ingreso de clientes...

¿Se entiende la idea?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
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 22:26.