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

convertir subconsulta en joins

Estas en el tema de convertir subconsulta en joins en el foro de Mysql en Foros del Web. que tal amigos tengo las siguientes 3 tablas Código PHP: CREATE TABLE  ` estudiante ` (   ` idestudiante `  int ( 10 )  unsigned NOT NULL auto_increment ,   ` correo ...
  #1 (permalink)  
Antiguo 10/02/2009, 18:15
Avatar de p4bl1t0  
Fecha de Ingreso: marzo-2006
Mensajes: 29
Antigüedad: 18 años, 2 meses
Puntos: 0
Exclamación convertir subconsulta en joins

que tal amigos tengo las siguientes 3 tablas

Código PHP:
CREATE TABLE `estudiante` (
  `
idestudianteint(10unsigned NOT NULL auto_increment,
  `
correovarchar(65) default NULL,
  `
usuario_idusuarioint(10unsigned NOT NULL default '0',
  
PRIMARY KEY  (`idestudiante`)
TYPE=MyISAM AUTO_INCREMENT=37 ;

INSERT INTO `estudianteVALUES (1'estudainteaws.com'91654123);
INSERT INTO `estudianteVALUES (2'elpopularpirishotmail.com'91519095);
INSERT INTO `estudianteVALUES (3'freddyhotmail.com'91654546);

CREATE TABLE `estudiantegrupo` (
  `
idestudiantegrupoint(10unsigned NOT NULL auto_increment,
  `
grupo_idgrupoint(10unsigned NOT NULL default '0',
  `
estudiante_idestudianteint(10unsigned NOT NULL default '0',
  
PRIMARY KEY  (`idestudiantegrupo`),
  
KEY `fkestudiante` (`estudiante_idestudiante`),
  
KEY `fkgrupo` (`grupo_idgrupo`)
TYPE=MyISAM AUTO_INCREMENT=;

INSERT INTO `estudiantegrupoVALUES (111);
INSERT INTO `estudiantegrupoVALUES (212);
INSERT INTO `estudiantegrupoVALUES (313);
INSERT INTO `estudiantegrupoVALUES (472);

CREATE TABLE `usuario` (
  `
idusuariovarchar(20NOT NULL default '',
  `
nombrevarchar(45) default NULL,
  `
apellidovarchar(45) default NULL,
  `
loginvarchar(20) default NULL,
  `
passvarchar(40) default NULL,
  `
perfilint(10unsigned default NULL,
  
PRIMARY KEY  (`idusuario`)
TYPE=MyISAM;

INSERT INTO `usuarioVALUES ('91519095''Jorge Hernando''Duarte''piris''fb3c94c67583056ed0c993cb60e8548b'3);
INSERT INTO `usuarioVALUES ('91654123''estudiante''estudiante''estudiante''f84b437e1ce2643aa5572ad53dd7d4ce'3);
INSERT INTO `usuarioVALUES ('171717171''freddy''mantilla''freddy1''a0137aae1e07f922372b7b5ca71a4ff9'4); 
y quiero visualizar todos los estudiantes que se encuentran en la tabla estudiantegrupo pero menos los que esten en el grupo 1, sin importar si estan en otro grupo, lo hago con la siguiente consulta que usa subconsulta

Código PHP:
select e.idestudiante as id,u.idusuario as documento,u.nombre as nombre,u.apellido as apellido,e.correo as correo
 from usuario u join estudiante e on u
.idusuario e.usuario_idusuario
 left join estudiantegrupo k on e
.idestudiante k.estudiante_idestudiante
 where 
(k.grupo_idgrupo is null or k.grupo_idgrupo != '1') and e.idestudiante not in (select estudiante_idestudiante from estudiantegrupo where grupo_idgrupo '1')
 
group by e.idestudiante
 order by e
.idestudiante asc 
lo uso en un servidor con mysql 5.0 y funciona correctamente, el problema es que tengo que hacerlo funcionar en mysql 4.0 y no sirven subconsultas, no puedo optar por aztualizar al version pro que eso no esta en mis manos.... asi que no se como hacerlo...., ya que si quito la subconsulta me muestra todos los estudiantes que menos los que estan en el grupo 1, pero si hay uno de esos mismos que esta en el grupo 2 tamb lo muestra...
bueno muchas gracias de antemano alq ue pueda ayudarme
  #2 (permalink)  
Antiguo 11/02/2009, 07:39
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: convertir subconsulta en joins

Código:
select e.idestudiante as id,
          u.idusuario as documento,
          u.nombre as nombre,
          u.apellido as apellido,
          e.correo as correo
 from (usuario u join estudiante e 
           on u.idusuario = e.usuario_idusuario)
             left join estudiantegrupo k 
                on e.idestudiante = k.estudiante_idestudiante
 group by e.idestudiante,
          u.idusuario,
          u.nombre,
          u.apellido,
          e.correo
 HAVING Min(k.grupo_idgrupo)>1 or Min(k.grupo_idgrupo) is null
 order by e.idestudiante asc;
Para el grupo 1 podria servir, para los otros no!!!

Quim

Última edición por quimfv; 11/02/2009 a las 09:50 Razón: He quitado los alias de group by era un error
  #3 (permalink)  
Antiguo 11/02/2009, 08:26
Avatar de p4bl1t0  
Fecha de Ingreso: marzo-2006
Mensajes: 29
Antigüedad: 18 años, 2 meses
Puntos: 0
Respuesta: convertir subconsulta en joins

gracias Quim por tu tiempo

pero no me hago entender bien, como podemos ver el estudiante jorge se encuentra vinculado a los grupos 1 y 7, lo que necesito es mostrar todos los estudiantes menos los que se encuentran en el grupo 1, el problema es que si un estudiante que se encuentra en el grupo 1 y en el 7 al mismo tiempo (como jorge), se mostrara, por el hecho que se encuentra en otro grupo fuera de estar en el grupo 1, y lo que se quiere es no mostrar los estudiantes que están en el grupo 1, sin importar si están en otro grupo también...

con la subconsulta que mostré anteriormente, logro hacer esto, pero yo no puedo usar subconsultas por la versión del mysql que esta usando el servidor en el que se esta montando la aplicación...
eh pensado que con joins podría hacerse, pero no se como hacerlo, o de otra forma..
bueno muchas gracias por su atención
  #4 (permalink)  
Antiguo 11/02/2009, 09:43
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: convertir subconsulta en joins

Si te he entendido, y se que hace la consulta que planteas, y tambien que no se puede ejecutar con mysql 4.X.

La solucion que te doy es parcial ya que solo funciona para el grupo 1.

Si jorge esta en los grupos 1 y 7 el grupo minimo de jorge es 1 por lo tanto no se mostrará por la condición de Min(k.grupo_idgrupo)>1. He puesto lo de or Min(k.grupo_idgrupo) is null por si hay estudiantes que no tienen grupo y los quieres en el listado.

Obteniendo el grupo minimo de cada estudiante y limitando el select a aquellos estudiandtes que tienen el grupo minimo mayor a 1 logras listar los estudiantes que no estan relacionados con el grupo uno, que es lo que entiendo que quieres hacer, no?

Claro esta que esto no sirve si el grupo a eliminar es el 2 o cualquier otro distinto de 1. Con una pequeña modificacion tambien serviria para eliminar los estudiantes del grupo con el numerador mas alto (cambiando min por max y buscando aquellos donde max(grupo)<numeradormaximo).



Quim

Última edición por quimfv; 11/02/2009 a las 09:53
  #5 (permalink)  
Antiguo 11/02/2009, 10:54
Avatar de p4bl1t0  
Fecha de Ingreso: marzo-2006
Mensajes: 29
Antigüedad: 18 años, 2 meses
Puntos: 0
Respuesta: convertir subconsulta en joins

Muchas gracias de nuevo Quim...

si funciono y veo que si entendías... el que no entendía era yo , jajaja

ahora el problema, es que lo que necesito es que que varié el numero del grupo, tanto como puede ser 1, 2, 3, 22, 34, etc, también los diferentes estudiantes pueden estar en diferentes grupos al mismo tiempo, de tal forma que jorge puede estar en el grupo 1, 2, 3, 5, 34, 12... y yo quiero que no lo muestre dependiendo el numero del grupo al que se lo envie....

estuve intentando como me comentaste de lo máximo y lo mínimo, y como es muy variable, me complique mucho, pienso que la validación del grupo podría hacerse desde php, para editar la consulta antes de enviarla a mysql....
algo así
Código PHP:
$contar "select e.idestudiante as id,u.idusuario as documento,u.nombre as nombre,u.apellido as apellido,e.correo as correo,k.grupo_idgrupo";
$contar .= " from usuario u join estudiante e on u.idusuario = e.usuario_idusuario";
$contar .= " left join estudiantegrupo k on e.idestudiante = k.estudiante_idestudiante";
$contar .= " group by e.idestudiante";
if(
$IdGrupo==1){ $contar .= " having k.grupo_idgrupo is null or min(k.grupo_idgrupo)!='$IdGrupo'"; }
if(
$IdGrupo>1){ $contar .= " having k.grupo_idgrupo is null or max(k.grupo_idgrupo)!='$IdGrupo'"; }
$contar .= " order by e.idestudiante asc"
bueno gracias por todo
  #6 (permalink)  
Antiguo 11/02/2009, 12:21
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: convertir subconsulta en joins

Hola p4bl1t0

Por favor lee esto: http://www.forosdelweb.com/f21/funci...-datos-413499/

Saludos
  #7 (permalink)  
Antiguo 11/02/2009, 12:50
Avatar de p4bl1t0  
Fecha de Ingreso: marzo-2006
Mensajes: 29
Antigüedad: 18 años, 2 meses
Puntos: 0
Respuesta: convertir subconsulta en joins

hola,
si, yo se que me desvié al colocar código php, pero eso es principalmente lo que yo quería evitar... lograr hacer esto que necesito sin necesidad de manipular la consulta con código php...
originalmente el problema es de SQL... bueno al que pueda ayudarme gracias por todo...
  #8 (permalink)  
Antiguo 11/02/2009, 14:28
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 1 mes
Puntos: 300
Respuesta: convertir subconsulta en joins

No sé si lo he entendido todo bien, pero si lo que quieres es que te muestre aquellos que no tengan grupo 1, aunque también tengan otro grupo, yo probaría esto, que creo que también te servirá para MySQL 4

Código sql:
Ver original
  1. SELECT e.idestudiante, e.correo, e.usuario_idusuario, u.nombre, u.apellido, u.login, u.pass, u.perfil
  2. FROM estudiante e
  3. INNER JOIN (
  4.  
  5. SELECT DISTINCT estudiante_idestudiante dato
  6. FROM estudiantegrupo eg
  7. LEFT JOIN (
  8.  
  9. SELECT estudiante_idestudiante dato
  10. FROM estudiantegrupo
  11. WHERE grupo_idgrupo =1
  12. )t1 ON eg.estudiante_idestudiante = t1.dato
  13. WHERE t1.dato IS NULL
  14. )t2 ON e.idestudiante = t2.dato
  15. INNER JOIN usuario u ON e.usuario_idusuario = u.idusuario

Creo que esto hace lo que quieres, y evita mostrar los que no estén incluidos en la tabla de grupos.

Última edición por jurena; 12/02/2009 a las 03:25
  #9 (permalink)  
Antiguo 11/02/2009, 14:45
Avatar de p4bl1t0  
Fecha de Ingreso: marzo-2006
Mensajes: 29
Antigüedad: 18 años, 2 meses
Puntos: 0
Respuesta: convertir subconsulta en joins

hola, gracias jurena...
pero veo que estas usando subconsultas... y como digo no puedo usarlas por que en el servidor en el que esta la aplicación, por que no las soporta...

gracias por tu tiempo
  #10 (permalink)  
Antiguo 11/02/2009, 17:42
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: convertir subconsulta en joins

Pensare en ello....

Quizas tendras que hacer dos consultas una busacando los id de los estudiantes del grupo "maldito" y luego construir el not in (id1,id2,di3,...,din) para la segunda consulta que seria como la que planteabas inicialmente pero sin la subconsulta. No se si saldria con sql creo que es mas facil apoyandose en programación, pero cualquiera pone un a p seguida de una h y otra p... .

Quim
  #11 (permalink)  
Antiguo 12/02/2009, 02:59
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 1 mes
Puntos: 300
Respuesta: convertir subconsulta en joins

Creo que voy a repetir la idea de quim (perdona, amigo):
Yo haría dos consultas para un MySQL que no acepta subconsultas:
1)
SELECT distinct idestudiantegrupo FROM `estudiantegrupo` WHERE grupo_idgrupo = 1

Encontrará, por ej., 1,3. Formas con programación esa cadena (pide ayuda en el foro PHP si lo necesitas) y la incluyes donde aparece el 1,3 en la siguiente consulta, que sería la segunda.

2) SELECT eg.idestudiantegrupo, u.nombre, u.apellido, u.login, u.pass, u.perfil, e.correo from estudiantegrupo eg inner join estudiante e on e.idestudiante = eg.idestudiantegrupo inner join usuario u on e.usuario_idusuario = u.idusuario where eg.idestudiantegrupo NOT IN(1,3)

Eso,aunque no lo he probado, creo que funcionaría, y es lo que ha recomendado quim, si lo he entendido bien. Sólo una aclaración: el inner join lo hago con la misma tabla estudiantegrupo para evitar que aparezca un estudiante que no forme parte de ningún grupo y que esté en la tabla estudiante.

Última edición por jurena; 12/02/2009 a las 03:26
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 19:43.