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

Problema combinando tablas

Estas en el tema de Problema combinando tablas en el foro de Mysql en Foros del Web. Hola buenas, Hasta un poco de vergüenza me da preguntar lo siguiente, porque aunque no soy ningún maestro sí que llevo años utilizando MySQL y ...
  #1 (permalink)  
Antiguo 29/02/2012, 17:13
 
Fecha de Ingreso: abril-2002
Mensajes: 1.014
Antigüedad: 22 años
Puntos: 8
Problema combinando tablas

Hola buenas,

Hasta un poco de vergüenza me da preguntar lo siguiente, porque aunque no soy ningún maestro sí que llevo años utilizando MySQL y otras bases de datos y hasta ahora no me había surgido nada así...

La siguiente combinación da el resultado mostrado en la imagen bajo ella (muestra todos los registros bien relacionados):

Código:
select per.idpersona, per.nombre, per.idprovincia, pro.idprovincia, pro.provincia
from personas per, provincias pro
where
(
	(per.idprovincia = pro.idprovincia) 
);


Pero la siguiente sentencia falla (deberían realizarse las condiciones sobre los datos resultantes de la combinación):

Código:
select per.idpersona, per.nombre, per.idprovincia, pro.idprovincia, pro.provincia
from personas per, provincias pro
where
(
	(per.idprovincia = pro.idprovincia)  AND
	(pro.provincia = 'LAS PALMAS') OR 
	(pro.idprovincia = 5)	
);


Sin embargo, del siguiente modo va perfecta (agrupando las condiciones entre paréntesis):

Código:
select per.idpersona, per.nombre, per.idprovincia, pro.idprovincia, pro.provincia
from personas per, provincias pro
where
(
	(per.idprovincia = pro.idprovincia)  AND
	( (pro.provincia = 'LAS PALMAS') OR (pro.idprovincia=5) )	
);


No termino de entender el por qué, nunca me había encontrado con algo así, incluso por si estaba confundido he vuelto a repasar ejercicios de hace años en que lo estudié... y están igual que lo indicado en el primer modo (sin necesidad de agrupar las condiciones tras la combinación).

Conozco los JOIN aunque por costumbre no los uso. La siguiente sentencia funciona bien:

Código:
select per.idpersona, per.nombre, per.idprovincia, pro.idprovincia, pro.provincia
from personas per INNER JOIN provincias pro ON (per.idprovincia = pro.idprovincia)
where
(
	(pro.provincia = 'LAS PALMAS') OR 
	(pro.idprovincia = 5)	
);
Las tablas son InnoDB con sus claves foráneas y demás.

Agradecería mucho una explicación dado que por más vueltas que le doy y por más material que repaso no doy con la solución.

PD: creo que me hago viejo

Última edición por MikiBroki; 29/02/2012 a las 18:28
  #2 (permalink)  
Antiguo 01/03/2012, 02:34
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Problema combinando tablas

Repasa la sintaxis, usa join... on és mejor.

Y sobre todo repasa la teoria de los operadores logicos.... una pista recuerda lo que pasa en matematicas entre la suma y el producto

2+3*5=17
2+(3*5)=17
(2+3)*5=25
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.
  #3 (permalink)  
Antiguo 01/03/2012, 02:54
 
Fecha de Ingreso: abril-2002
Mensajes: 1.014
Antigüedad: 22 años
Puntos: 8
Respuesta: Problema combinando tablas

Sí amigo, todo eso lo se, conozco bien el álgebra relacional así como la precedencia de operadores, tablas de la verdad y los diferentes tipos de join (LEFT, RIGHT...) y cómo definirlos en el FROM... pero en su día en SQL me enseñaron la forma de combinar las tablas en WHERE (se que se puede hacer con NATURAL JOIN también).

En el ejemplo, sin poner condiciones se devuelven según lo esperado... y es por eso que no entiendo que no funcione esto y necesitaría saber el por qué.

O sea, en su día la explicación sobre la combinación era: se combinan las tablas para obtener una fila con los campos deseados, y luego A PARTIR DE ESE RESULTADO se establecen las condiciones... y éstas no había que agruparlas entre paréntesis (en casos como este me refiero)... y es que siempre lo he usado y visto usar de este modo sin problema... ¿qué diferencia hay entre hacer este tipo de join en el where o en FROM?

La segunda y cuarta consultas se supone que hacen lo mismo, así que no entiendo.

Última edición por MikiBroki; 01/03/2012 a las 03:34
  #4 (permalink)  
Antiguo 01/03/2012, 06:24
 
Fecha de Ingreso: abril-2002
Mensajes: 1.014
Antigüedad: 22 años
Puntos: 8
Respuesta: Problema combinando tablas

Básicamente la pregunta viene a ser, qué diferencia hay entre estas dos consultas, porque aunque se dice que es lo mismo parece que no funcionan exactamente igual a la hora de obtener los datos, ya que parece que en la segunda se aplican las condiciones a los datos obtenidos por el INNER JOIN pero en la primera no es exactamente así, sino que el hecho de realizar la combinación no fuerza a que el resto de condiciones se hagan todas sobre el resultado... ¿me he respondido bien yo solo?:

-----------

select per.idpersona, per.nombre, per.idprovincia, pro.idprovincia, pro.provincia
from personas per, provincias pro
where
(
(per.idprovincia = pro.idprovincia) AND
(pro.provincia = 'LAS PALMAS') OR
(pro.idprovincia = 5)
);

-----------

select per.idpersona, per.nombre, per.idprovincia, pro.idprovincia, pro.provincia
from personas per INNER JOIN provincias pro ON (per.idprovincia = pro.idprovincia)
where
(
(pro.provincia = 'LAS PALMAS') OR
(pro.idprovincia = 5)
);

-----------
  #5 (permalink)  
Antiguo 01/03/2012, 07:53
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Problema combinando tablas

La restricción

per.idprovincia = pro.idprovincia

sirve para relacionar registros de las dos tablas

mientras que las otras dos sirven para seleccionar registros del resultado de la combinación de tablas.



Hasta aqui coincidimos, no?



En el segundo caso el motor tiene muy claro que es lo que tiene que hacer

Combinar por per.idprovincia = pro.idprovincia
y
Selecionar por (pro.provincia = 'LAS PALMAS') OR (pro.idprovincia = 5)



Si?


Mientras que en el primer ejemplo el motor

No sabe que restricción sirve para combinar por lo que hace un producto cartesiano de las dos tablas y

Selecciona por (per.idprovincia = pro.idprovincia) AND
(pro.provincia = 'LAS PALMAS') OR
(pro.idprovincia = 5)


es decir A y B o C

que por precedencia de operadores son todos los registros donde se cumpla A y B por un lado y los que cumplen C (solo C).


Si?


Para que los dos casos sean equivalentes deberías agregar parentesis

select per.idpersona, per.nombre, per.idprovincia, pro.idprovincia, pro.provincia
from personas per, provincias pro
where
(
(per.idprovincia = pro.idprovincia) AND
((pro.provincia = 'LAS PALMAS') OR
(pro.idprovincia = 5))
);

es decir A y (B o C)

los que cumplen A y una de las otras dos (B o C).


Si?


La diferencia entre una sintaxis y la otra es que con JOIN...ON queda mucho mas claro que hace cada cosa con lo que és mucho más facil resolver dudas como esta. Ademas, y quizas lo mas importante, le ahorra al motor hacer un producto cartesiano.

Obviamente si en las restricciones no hubiera ninguna O (OR) no habrias tenido ningun problema... cuando se combinan ANDs y ORs hay que ir con mucho cuidado.

Finalmente la sintaxis JOIN ...ON hoy en dia es la que se considera estandar.

Si no ves algo claro pregunta. Por cierto esto ya funcionaba así en su dia....
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.

Última edición por quimfv; 01/03/2012 a las 08:37
  #6 (permalink)  
Antiguo 01/03/2012, 08:18
 
Fecha de Ingreso: abril-2002
Mensajes: 1.014
Antigüedad: 22 años
Puntos: 8
Respuesta: Problema combinando tablas

Excelente explicación que me termina de aclarar todo.

Siempre me habían explicado (o yo no terminé de entender bien) ademas de ver en varias web que comentaban que daba igual usar ambos métodos pero sin comentar la diferencia, y por lo tanto entendía que aparte de la relación se hacía también la selección... y de ahí mi confusión.

Siempre está uno aprendiendo algo nuevo.

Un cordial saludo y un millón de gracias !

Etiquetas: join, registros, select, sql, tablas
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 18:03.