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

Resultados no coincidentes con JOIN

Estas en el tema de Resultados no coincidentes con JOIN en el foro de Mysql en Foros del Web. Buenas, foreros. Hay algo que no comprendo en los resultados arrojados por unas consultas MySQL: Código: SELECT * from tabla1 inner join tabla2 on tabla2.id_usuario ...
  #1 (permalink)  
Antiguo 09/11/2009, 15:44
 
Fecha de Ingreso: junio-2007
Ubicación: Buenos Aires, Argentina
Mensajes: 262
Antigüedad: 16 años, 10 meses
Puntos: 1
Resultados no coincidentes con JOIN

Buenas, foreros. Hay algo que no comprendo en los resultados arrojados por unas consultas MySQL:

Código:
 
SELECT * from tabla1 inner join tabla2 on tabla2.id_usuario = from tabla1.id 
where from tabla1.desregistrado = '0' and tabla2.id_grupo = 4;
da 1.994 resultados.

y

Código:
 
SELECT * from tabla1 inner join tabla2 on tabla2.id_usuario = from tabla1.id 
where from tabla1.desregistrado = '0' and tabla2.id_grupo <> 4;
da 1 resultado.

El total de resultados, sin buscar por grupo, es de 1.997. No comprendo cómo, si sumo lo que es igual a algo y lo que es diferente a algo, puede darme un resultado diferente al total de filas que hay en la tabla.

Creo que el problema debe estar en el "join", pero no sé bien de qué forma.

¿Alguien tiene alguna idea?

Gracias!
Pablo
__________________
Moebius Digital | La pieza que faltaba
Diseño web | Web hosting
  #2 (permalink)  
Antiguo 09/11/2009, 16:00
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: Resultados no coincidentes con JOIN

vaya si es raro.

Te debería dar la suma de la totalidad.

Postea la estructura de las tablas y algunos datos para hacer pruebas.

es bastante raro. hice una prueba sencilla y no tuve el problema.
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #3 (permalink)  
Antiguo 10/11/2009, 09:13
 
Fecha de Ingreso: junio-2007
Ubicación: Buenos Aires, Argentina
Mensajes: 262
Antigüedad: 16 años, 10 meses
Puntos: 1
Respuesta: Resultados no coincidentes con JOIN

Gracias por tu respuesta, huesos52. Aquí va la estructura:

Código:
 
tabla1 (
  `id` bigint(20) NOT NULL auto_increment
  `id_foro` int(11) default NULL
  `nombre` varchar(255) default NULL
  `mail` varchar(255) NOT NULL
  `desregistrado` tinyint(2) NOT NULL
  `fechaingreso` datetime NOT NULL,
  `mailmd5` varchar(32) NOT NULL
  PRIMARY KEY  (`id`),
  UNIQUE KEY `mail` (`mail`),
  UNIQUE KEY `mailmd5` (`mailmd5`)
) 


tabla2 (
  `id_usuario` bigint(20) NOT NULL,
  `id_grupo` bigint(20) NOT NULL,
  PRIMARY KEY  (`id_usuario`,`id_grupo`),
  KEY `id_grupo` (`id_grupo`)
)
Estoy muy desconcertado.
¿Alguna idea?

Gracias!
Pablo
__________________
Moebius Digital | La pieza que faltaba
Diseño web | Web hosting
  #4 (permalink)  
Antiguo 10/11/2009, 09:23
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, 5 meses
Puntos: 2658
Respuesta: Resultados no coincidentes con JOIN

Cita:
Creo que el problema debe estar en el "join", pero no sé bien de qué forma.
No necesariamente. El complemento de:
Código sql:
Ver original
  1. SELECT *
  2. FROM tabla1 INNER JOIN tabla2 ON tabla2.id_usuario = tabla1.id
  3. WHERE tabla1.desregistrado = '0' AND tabla2.id_grupo = 4;
no es:
Código sql:
Ver original
  1. SELECT *
  2. FROM tabla1 INNER JOIN tabla2 ON tabla2.id_usuario = tabla1.id
  3. WHERE tabla1.desregistrado = '0' AND tabla2.id_grupo <> 4;
sino:
Código sql:
Ver original
  1. SELECT *
  2. FROM tabla1 INNER JOIN tabla2 ON tabla2.id_usuario = tabla1.id
  3. WHERE tabla1.desregistrado <> '0' AND tabla2.id_grupo <> 4;
o bien:
Código sql:
Ver original
  1. SELECT *
  2. FROM tabla1 INNER JOIN tabla2 ON tabla2.id_usuario = tabla1.id
  3. WHERE NOT (tabla1.desregistrado = '0' AND tabla2.id_grupo = 4);
desde el momento en que el WHERE tiene dos condiciones, no una. Por lo tanto el complemento debe incluir la negación de las dos.

Pruebalo y veamos.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 10/11/2009, 09:26
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: Resultados no coincidentes con JOIN

No sabría que decirte. haciendo pruebas con pocos registros fijate bien:

Código mysql:
Ver original
  1. mysql> SELECT * from tabla1 inner join tabla2 on tabla2.id_usuario = tabla1.id
  2.     -> where tabla1.desregistrado = 0;
  3. +----+---------+--------+-------+---------------+---------------------+---------+------------+----------+
  4. | id | id_foro | nombre | mail  | desregistrado | fechaingreso        | mailmd5 | id_usuario | id_grupo |
  5. +----+---------+--------+-------+---------------+---------------------+---------+------------+----------+
  6. |  1 |       1 | daniel | mail1 |             0 | 2009-11-10 10:19:43 | mail1   |          1 |        1 |
  7. |  1 |       1 | daniel | mail1 |             0 | 2009-11-10 10:19:43 | mail1   |          1 |        2 |
  8. |  1 |       1 | daniel | mail1 |             0 | 2009-11-10 10:19:43 | mail1   |          1 |        3 |
  9. |  1 |       1 | daniel | mail1 |             0 | 2009-11-10 10:19:43 | mail1   |          1 |        4 |
  10. |  2 |       1 | daniel | mail2 |             0 | 2009-11-10 10:19:51 | mail2   |          2 |        4 |
  11. |  3 |       1 | daniel | mail3 |             0 | 2009-11-10 10:20:00 | mail3   |          3 |        4 |
  12. |  4 |       1 | daniel | mail4 |             0 | 2009-11-10 10:20:46 | mail4   |          4 |        4 |
  13. +----+---------+--------+-------+---------------+---------------------+---------+------------+----------+
  14. 7 rows in set (0.00 sec)

Sin condición muestra 7 registros.

Código mysql:
Ver original
  1. mysql> SELECT * from tabla1 inner join tabla2 on tabla2.id_usuario = tabla1.id
  2.     -> where tabla1.desregistrado = 0 and tabla2.id_grupo = 4;
  3. +----+---------+--------+-------+---------------+---------------------+---------+------------+----------+
  4. | id | id_foro | nombre | mail  | desregistrado | fechaingreso        | mailmd5 | id_usuario | id_grupo |
  5. +----+---------+--------+-------+---------------+---------------------+---------+------------+----------+
  6. |  1 |       1 | daniel | mail1 |             0 | 2009-11-10 10:19:43 | mail1   |          1 |        4 |
  7. |  2 |       1 | daniel | mail2 |             0 | 2009-11-10 10:19:51 | mail2   |          2 |        4 |
  8. |  3 |       1 | daniel | mail3 |             0 | 2009-11-10 10:20:00 | mail3   |          3 |        4 |
  9. |  4 |       1 | daniel | mail4 |             0 | 2009-11-10 10:20:46 | mail4   |          4 |        4 |
  10. +----+---------+--------+-------+---------------+---------------------+---------+------------+----------+
  11. 4 rows in set (0.02 sec)

Con condición =4 muestra 4.

Código mysql:
Ver original
  1. mysql> SELECT * from tabla1 inner join tabla2 on tabla2.id_usuario = tabla1.id
  2.     -> where tabla1.desregistrado = 0 and tabla2.id_grupo <> 4;
  3. +----+---------+--------+-------+---------------+---------------------+---------+------------+----------+
  4. | id | id_foro | nombre | mail  | desregistrado | fechaingreso        | mailmd5 | id_usuario | id_grupo |
  5. +----+---------+--------+-------+---------------+---------------------+---------+------------+----------+
  6. |  1 |       1 | daniel | mail1 |             0 | 2009-11-10 10:19:43 | mail1   |          1 |        1 |
  7. |  1 |       1 | daniel | mail1 |             0 | 2009-11-10 10:19:43 | mail1   |          1 |        2 |
  8. |  1 |       1 | daniel | mail1 |             0 | 2009-11-10 10:19:43 | mail1   |          1 |        3 |
  9. +----+---------+--------+-------+---------------+---------------------+---------+------------+----------+
  10. 3 rows in set (0.00 sec)

Con condición <>4 muestra 3.

Desde donde haces las pruebas?
directamente en mysql o desde el lenguaje de programación?
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #6 (permalink)  
Antiguo 11/11/2009, 08:29
 
Fecha de Ingreso: junio-2007
Ubicación: Buenos Aires, Argentina
Mensajes: 262
Antigüedad: 16 años, 10 meses
Puntos: 1
Respuesta: Resultados no coincidentes con JOIN

Cita:
Iniciado por huesos52 Ver Mensaje
Desde donde haces las pruebas?
directamente en mysql o desde el lenguaje de programación?
Empecé programándolo en PHP, pero al ver esta discordancia hice las consultas directamente desde el phpMyAdmin, y da los mismos resultados.



Cita:
Iniciado por gnzsoloyo Ver Mensaje
desde el momento en que el WHERE tiene dos condiciones, no una. Por lo tanto el complemento debe incluir la negación de las dos.
Es cierto, gnzsoloyo, me expresé mal. Estoy buscando todos los desregistrados = 0. De todas formas, siendo que lo mismo pasa excluyendo esta condición, sigamos analizándolo sin ella (paso a usar los nombres reales de las tablas, así no edito tanto el código para cada copy+paste):

Código mysql:
Ver original
  1. SELECT count( * ) AS total
  2. FROM mailer_direcciones
  3. LEFT JOIN mailer_direcc_grupo
  4. ON mailer_direcc_grupo.id_usuario = mailer_direcciones.id;
Total = 2006

Código mysql:
Ver original
  1. SELECT count( * ) AS total
  2. FROM mailer_direcciones
  3. LEFT JOIN mailer_direcc_grupo
  4. ON mailer_direcc_grupo.id_usuario = mailer_direcciones.id
  5. where mailer_direcc_grupo.id_grupo = 4;
Total = 2003

Código mysql:
Ver original
  1. SELECT count( * ) AS total
  2. FROM mailer_direcciones
  3. LEFT JOIN mailer_direcc_grupo
  4. ON mailer_direcc_grupo.id_usuario = mailer_direcciones.id
  5. WHERE mailer_direcc_grupo.id_grupo <>4;
Total = 1

Sigue dando la misma diferencia. Hay dos registros que no se contabilizan ni en una condición ni en la contraria.

Estuve haciendo más pruebas, y lo mismo pasa si hago una consulta en la tabla mailer_direcc_grupo, busco todas las que corresponden a un grupo, y uso sus IDs para buscar si están desregistradas o no (algo completamente ineficiente). Da la misma diferencia.

¿Creen que puede haber algún inconveniente en el armado de las tablas?

Muchas gracias!
Pablo
__________________
Moebius Digital | La pieza que faltaba
Diseño web | Web hosting
  #7 (permalink)  
Antiguo 11/11/2009, 09:25
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 1 mes
Puntos: 300
Respuesta: Resultados no coincidentes con JOIN

Por lo que se refiere a esto último, creo que tienes mailer_direcciones.id para los que no tienes ningún mailer_direcc_grupo.id_usuario, y la búsqueda left join cuenta todos los de la tabla situada a la izquierda o en primer lugar. Cuando haces la consulta sin el parámetro de número o no número, te cuenta todos los registros de la tabla primera, tengan o no relación en la otra tabla; si le incluyes el parámetro, ya no se contarán. Es lo que se me ocurre.
Busca
SELECT* FROM mailer_direcciones LEFT JOIN mailer_direcc_grupo ON mailer_direcc_grupo.id_usuario = mailer_direcciones.id WHERE mailer_direcc_grupo.id_usuario IS NULL

a ver si encuentras esos dos registros perdidos.
  #8 (permalink)  
Antiguo 12/11/2009, 00:13
 
Fecha de Ingreso: junio-2007
Ubicación: Buenos Aires, Argentina
Mensajes: 262
Antigüedad: 16 años, 10 meses
Puntos: 1
Respuesta: Resultados no coincidentes con JOIN

¡Maravilloso! eso era. Uf, qué trabajito que dio encontrarlos...
¿Cómo me recomendás, jurena, hacer la búsqueda para que no cuente los que tienen valor nulo en el id_usuario? ¿sería como a continuación?

Código mysql:
Ver original
  1. SELECT* FROM mailer_direcciones
  2. LEFT JOIN mailer_direcc_grupo
  3. ON mailer_direcc_grupo.id_usuario = mailer_direcciones.id
  4. WHERE mailer_direcc_grupo.id_usuario IS NOT NULL

Muchas gracias!
Pablo
__________________
Moebius Digital | La pieza que faltaba
Diseño web | Web hosting
  #9 (permalink)  
Antiguo 12/11/2009, 00:34
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 1 mes
Puntos: 300
Respuesta: Resultados no coincidentes con JOIN

Lo que no entiendo es por qué quieres contar usando LEFT JOIN. Si quieres contar los que tienen algún dato en mailer_direc_grupo tendrías que usar INNER JOIN. Respecto a lo que me dices, te recomiendo mejor esta consulta:
Código sql:
Ver original
  1. SELECT * FROM mailer_direcciones INNER JOIN mailer_direcc_grupo ON mailer_direcc_grupo.id_usuario = mailer_direcciones.id
Esta consigue lo mismo, pero de manera más eficiente que la que tú propones. Naturalmente, no te mostrará los datos de mailer_direcciones para los que no haya referencias en mailer_direcc_grupo, y eso es lo que quieres ¿no?

Última edición por jurena; 12/11/2009 a las 01:57
  #10 (permalink)  
Antiguo 12/11/2009, 07:39
 
Fecha de Ingreso: junio-2007
Ubicación: Buenos Aires, Argentina
Mensajes: 262
Antigüedad: 16 años, 10 meses
Puntos: 1
Respuesta: Resultados no coincidentes con JOIN

Asunto resueltísimo. ¡Muchas gracias a todos!

Pablo
__________________
Moebius Digital | La pieza que faltaba
Diseño web | Web hosting
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 20:06.