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

Problema con una consulta anidada

Estas en el tema de Problema con una consulta anidada en el foro de Mysql en Foros del Web. Hola, estoy haciendo una consulta a dos tablas: productos y subproducto. Ambas tienen in id en común: idPro tabla productos: idPro nomPro tabla subproducto: idSubPro ...
  #1 (permalink)  
Antiguo 04/06/2011, 12:36
 
Fecha de Ingreso: julio-2007
Mensajes: 287
Antigüedad: 16 años, 8 meses
Puntos: 4
Pregunta Problema con una consulta anidada

Hola, estoy haciendo una consulta a dos tablas: productos y subproducto.
Ambas tienen in id en común: idPro

tabla productos:
idPro
nomPro

tabla subproducto:
idSubPro
idPro
nomSubPro

Al realizar la consulta:

Código PHP:
select from productos,subproducto where productos.idPro subproducto.idPro
El resultado que necesito de esa consulta debería ser:

Productos:
Poleras de Algodón:
Poleras Rojas
Poleras Blancas
Poleras Amarillas


Pero me esta duplicando el producto por cada subproducto, o sea:

Productos:
Poleras de Algodón:
Poleras Rojas

Poleras de Algodón:
Poleras Blancas

Poleras de Algodón:
Poleras Amarillas

Espero se entienda el problema.

Alguien me puede dar una mano con esta cuery?
  #2 (permalink)  
Antiguo 04/06/2011, 13:25
 
Fecha de Ingreso: marzo-2009
Mensajes: 76
Antigüedad: 15 años, 1 mes
Puntos: 1
Respuesta: Problema con una consulta anidada

Yo te diria que te acostumbres a usar los JOINS

Código SQL:
Ver original
  1. SELECT * FROM productos INNER JOIN subproducto ON productos.idPro = subproductos.idPro;

si te ocurre con repeticiones por poner la palabra DISTINCT

Espero que sirva te aconsejo que leas un poco de JOIN son faciles de usar y mejoran el rendimiento y se entienden mejor las consultas.

Saludos.

NicoStone
  #3 (permalink)  
Antiguo 04/06/2011, 13:44
 
Fecha de Ingreso: julio-2007
Mensajes: 287
Antigüedad: 16 años, 8 meses
Puntos: 4
Pregunta Respuesta: Problema con una consulta anidada

hola!

probé de la forma que me indicas:

Código PHP:
SELECT DISTINCT FROM productos INNER JOIN subproducto ON productos.idPro subproducto.idPro group by productos.idPro
y para que no me duplicara coloque group by productos.idPro

Ahora no lo esta duplicando pero me muestra solo un subproducto asociado al producto y debería mostrarme todos los subproductos.

Alguna idea amigo?
de antemano gracias.
  #4 (permalink)  
Antiguo 04/06/2011, 16:43
 
Fecha de Ingreso: julio-2007
Mensajes: 287
Antigüedad: 16 años, 8 meses
Puntos: 4
Respuesta: Problema con una consulta anidada

Alguien tiene una idea de como resolver este problemilla?

Lo que pretendo hacer es que me muestre el nombre del producto y todos los subproductos asociados a dicho productos. Creo que será mejor pegar todo el Código por si alguien se anima a darme una mano.


Código PHP:
Ver original
  1. $sql="SELECT * FROM productos INNER JOIN subproducto ON productos.idPro = subproducto.idPro and productos.valor='si' and subproducto.valor='si' group by productos.idPro";
  2.                         $res=mysql_query($sql)or die(mysql_error);
  3.                         while($row=mysql_fetch_array($res))
  4.                             {
  5.                             $idPro=$row['idPro'];
  6.                             $nomPro=$row['nomPro'];
  7.                             $idSubPro=$row['idSubPro'];
  8.                             $nomSubPro=$row['nomSubPro'];
  9.                            
  10.                                 echo "
  11.                                 <strong>$nomPro:</strong><br/>
  12.                                     <a href='#?idSubPro=$idSubPro'class='link2'>$nomSubPro</a>[HIGHLIGHT="PHP"]
";

}
[/HIGHLIGHT]

Y como decía espero el siguiente resultado:

EJE:

POLERAS:
Poleras Rojas
Poletas Amarillas
Poletas Azules

PANTALONES:
Pantalones café
Pantalones Verdes

y hasta el momento solo me muestra un subproducto de cada producto. Debería Mostrar todos los subproductos asociados a cada producto.

Alguna Mano Porfa...
  #5 (permalink)  
Antiguo 05/06/2011, 20:19
 
Fecha de Ingreso: julio-2007
Mensajes: 287
Antigüedad: 16 años, 8 meses
Puntos: 4
Respuesta: Problema con una consulta anidada

perdonen que insista con el tema pero necesito ayuda!

Estoy intentando listar todos los subProductos asociados a un Producto. (como he puesto en el ejemplo más arriba)

Cada productos ya tiene asociado varios subproductos, pero cuando los listo solo me muestra un subproducto por cada producto, siendo que debería listarlos todos.

no se cual es el problema. También he puesto el código que estoy utilizando.

Ayuda plis!!
  #6 (permalink)  
Antiguo 09/06/2011, 21:37
 
Fecha de Ingreso: julio-2007
Mensajes: 287
Antigüedad: 16 años, 8 meses
Puntos: 4
Respuesta: Problema con una consulta anidada

..no creí que fuera tan complicado hacer esto.
Muchas gracias tu apoyo nicostone.
  #7 (permalink)  
Antiguo 09/06/2011, 21: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: 16 años, 4 meses
Puntos: 2658
Respuesta: Problema con una consulta anidada

El problema no es que sea complicado. Es que es algo medio aburrido (sin ofender), porque el inconveniente es que no pareces conocer cómo funciona el JOIN (o su equivalente: la coma).
Como es un tema repetitivo, que cada tanto aparece, y siempre tiene el mismo origen, no estimula contestarlo. Creo que todos quedamos esperando a que te des cuenta que deberías leer más sobre el tema de los JOIN, como te sugirió nicostone:
Cita:
Espero que sirva te aconsejo que leas un poco de JOIN son fáciles de usar y mejoran el rendimiento y se entienden mejor las consultas.
El asunto es así:
El JOIN hace de base una junta natural sobre los campos que lleven el mismo nombre, pero no discrimina los valores, sino que trata de igualar campos que tienen el mismo nombre. Si estos campos no representan el mismo dato, MySQL no lo sabe, lo hará lo mismo, y generará una combinación entre cada registro de la primera con cada uno de los de la segunda tabla. Como te imaginarás eso genera una multiplicación lógica.
Esa es la base de tu problema. Por ello se hacen con condiciones que indiquen qué campos se relacionan. En el estandar antiguo eso se ahcía en el WHERE; hoy no se recomienda y se aconseja usar JOIN ... ON ...
Por otro lado, tienes que entender que al hacer un JOIN con condiciones sobre uno o más campo, sólo devolverá aquellos donde se cumpla la condición, pero (y esto es importante), si la primera tabla se combina con varios registros de la segunda, los campos que provengan de la primera tabla se repetirán una vez por cada caso en que haya coincidencias en la segunda tabla.
En el contexto de tu caso eso significa que si la tabla Productos contiene
Cita:
Poleras de Algodón:
Poleras Rojas
Poleras Blancas
Poleras Amarillas
Esos se repetirán cada vez que haya un valor en la tabla Subproducto donde estén relacionados. Lo que no se repetirá es la combinación entre ambas tablas.
¿Se entiende? No existe la repetición si las columnas correspondientes a las egunda tabla no se repiten.

A no confundir...
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #8 (permalink)  
Antiguo 09/06/2011, 22:18
 
Fecha de Ingreso: julio-2007
Mensajes: 287
Antigüedad: 16 años, 8 meses
Puntos: 4
Respuesta: Problema con una consulta anidada

Agradezco mucho el comentario.

Como podrás notar hice uso del JOIN...ON como me lo sugirió nicostone, a quién agradezco también su tiempo. Investigue sobre aquello pero definitivamente no he logrado dar con la solución. He tratado de documentarme lo mejor posible, así he aprendido bastante diría yo. Entiendo que sea aburrido "mi problema" para las personas que tiene más experiencia amigo. Si no estuviera tan complicado con el desarrollo de esto no molestaría tanto. Aún cuando una amigo una ves me dijo..."no temas en preguntar como se hace, así aprendimos todos".
  #9 (permalink)  
Antiguo 09/06/2011, 22:23
 
Fecha de Ingreso: julio-2007
Mensajes: 287
Antigüedad: 16 años, 8 meses
Puntos: 4
Respuesta: Problema con una consulta anidada

Esto es lo último que he probado pero me arroja un error que no he descubierto.
Código PHP:
<?php
$consulta1 
"SELECT * FROM productos";
        
$result mysql_query($consulta1);
        
$cantidad mysql_num_rows($result1);
                        
        for(
$i=0$i $cantidad$i++)
            {
                
$row mysql_fetch_array($result1);
                
                    
$idPro $row['idPro'];
                    
$nomPro $row['nomPro'];
 
                 
$consulta2 "SELECT * FROM subproducto WHERE idPro = $idPro";
                 
$result2=mysql_query($consulta2);
                 while(
$row2=mysql_fetch_array($result2))
                         {
                         
$idSubPro $row2['idSubPro'];
                         
$nomSubPro $row2['nomSubPro'];
                        
                         echo 
"<div class='boxNomProd'><strong>$nomSubPro: </strong><br/>
                         <div class='textoSubPro'>
                         <a href='#?idSubPro=$idSubPro'class='link2'>$nomSubPro</a>
                         </div>"
;
                        }
            }
?>
Y por favor... perdonen que insista, pero la verdad no se que hacer. Debo tenerlo resuelto.
  #10 (permalink)  
Antiguo 10/06/2011, 03:16
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, 4 meses
Puntos: 2658
Respuesta: Problema con una consulta anidada

Lo que pasa es que el problema que mencionas no se ve en las consultas (tampoco se ningun error de sintaxis en el SQL, a menos que se produzca porque la variable usada en la búsqueda esté llegando vacía).
¿Podrías postear un ejemplo de los datos reales que tienen las tablas, y si es posible la estructura (el CREATE TABLE...) de ambas.
A veces algunos problemas se esconden allí.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #11 (permalink)  
Antiguo 10/06/2011, 07:57
 
Fecha de Ingreso: julio-2007
Mensajes: 287
Antigüedad: 16 años, 8 meses
Puntos: 4
Respuesta: Problema con una consulta anidada

Hola, estas son las tablas y los campos en cada una de ellas:

tabla productos:

idPro int(3) key - auto_increment
valor varchar(2)
nomPro varchar(100)
carPro text

tabla subproducto:

idSubPro int(3) key - auto_incremet
idPro int(3)
valor varchar(2)
nomSubPro varchar(100)
desSubPro text
ruta varchar(100)

De verdad agradezco mucho tu ayuda.
Muchas gracias.
  #12 (permalink)  
Antiguo 10/06/2011, 08:11
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, 4 meses
Puntos: 2658
Respuesta: Problema con una consulta anidada

Podrías probar usando
Código MySQL:
Ver original
  1. SHOW CREATE TABLE productos;
  2. SHOW CREATE TABLE subproductos;
y que copies el resultado de cada una de estas consultas.
Me interesa ver la definición exacta de la tabla, porque puede haber cosas que no salgan en una descripción sucinta como la que pones.

En principio, parecen estar correctamente relacionadas (lo veremos bien en el CREATE).
Me gustaría ver una tabla resultado de la consulta. ¿qué estás usando para probar las consultas? ¿phpMyAdmin u otra cosa?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #13 (permalink)  
Antiguo 10/06/2011, 08:22
 
Fecha de Ingreso: julio-2007
Mensajes: 287
Antigüedad: 16 años, 8 meses
Puntos: 4
Respuesta: Problema con una consulta anidada

OK, espero que con esto esté bien.
Gracias gnzsoloyo.

CREATE TABLE `productos` (
`idPro` int(3) NOT NULL AUTO_INCREMENT,
`valor` varchar(2) NOT NULL,
`nomPro` varchar(100) NOT NULL,
`carPro` text NOT NULL,
PRIMARY KEY (`idPro`)
)

INSERT INTO `productos` VALUES(2, 'si', 'Dúctos de Ventilación de PVC', '');
INSERT INTO `productos` VALUES(6, 'no', 'Manejadores de Aire', '');
INSERT INTO `productos` VALUES(3, 'si', 'Ventiladores Eléctricos Axiales', '');
INSERT INTO `productos` VALUES(4, 'no', 'Ventilador Neumático Axial', '¿Que es un Ventilador Neumático?');
INSERT INTO `productos` VALUES(5, 'no', 'Ventilador Centrífugo', '¿Que es un Ventilador Centrífugo?');
INSERT INTO `productos` VALUES(7, 'no', 'Dampers', '¿Que son los Dampers?');
INSERT INTO `productos` VALUES(8, 'no', 'Silenciadores', '¿Que son los silenciadores?');
INSERT INTO `productos` VALUES(9, 'no', 'Tableros Eléctricos', '¿Que son los tableros eléctiros?');

-------------------------------------------------------------------

CREATE TABLE `subproducto` (
`idSubPro` int(3) NOT NULL AUTO_INCREMENT,
`idPro` int(3) NOT NULL,
`valor` varchar(2) NOT NULL,
`nomSubPro` varchar(100) NOT NULL,
`desSubPro` text NOT NULL,
`ruta` varchar(100) NOT NULL,
PRIMARY KEY (`idSubPro`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;

INSERT INTO `subproducto` VALUES(1, 2, 'si', 'Ducto Impelante de PVC', 'dwcasdcasd', '');
INSERT INTO `subproducto` VALUES(2, 2, 'si', 'Ducto Aspirante de PVC', 'asvadva', '');
INSERT INTO `subproducto` VALUES(3, 3, 'si', 'Ventilador Axial tipo A', '', '');
INSERT INTO `subproducto` VALUES(4, 3, 'si', 'Ventilador Axial tipo B', '', '');
INSERT INTO `subproducto` VALUES(5, 2, 'si', 'codo para ducto de ventilación', 'asdvasdv', '');
INSERT INTO `subproducto` VALUES(6, 5, 'si', 'Ventilador Centrífugo Tipo H', '', '');
  #14 (permalink)  
Antiguo 10/06/2011, 09:04
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, 4 meses
Puntos: 2658
Respuesta: Problema con una consulta anidada

Gracias por la data.
Reconstruí estas dos tablas y las cargué con lo que me pasaste, luego de lo cual hice dos consultas. La primera usando tu primer post; la segunda haciendo un INNER JOIN mejorado:
Código MySQL:
Ver original
  1. mysql> SELECT *
  2.     -> FROM productos,subproducto
  3.     -> WHERE productos.idPro = subproducto.idPro;
  4. +-------+-------+---------------------------------+-----------------------------------+----------+-------+-------+--------------------------------+------------+------+
  5. | idPro | valor | nomPro                          | carPro                            | idSubPro | idPro | valor | nomSubPro                      | desSubPro  | ruta |
  6. +-------+-------+---------------------------------+-----------------------------------+----------+-------+-------+--------------------------------+------------+------+
  7. |     2 | si    | D·ctos de Ventilaci¾n de PVC    |                                   |        1 |     2 | si    | Ducto Impelante de PVC         | dwcasdcasd |      |
  8. |     2 | si    | D·ctos de Ventilaci¾n de PVC    |                                   |        2 |     2 | si    | Ducto Aspirante de PVC         | asvadva    |      |
  9. |     3 | si    | Ventiladores ElÚctricos Axiales |                                   |        3 |     3 | si    | Ventilador Axial tipo A        |            |      |
  10. |     3 | si    | Ventiladores ElÚctricos Axiales |                                   |        4 |     3 | si    | Ventilador Axial tipo B        |            |      |
  11. |     2 | si    | D·ctos de Ventilaci¾n de PVC    |                                   |        5 |     2 | si    | codo para ducto de ventilaci¾n | asdvasdv   |      |
  12. |     5 | no    | Ventilador CentrÝfugo           | &#9488;Que es un Ventilador CentrÝfugo? |        6 |     5 | si    | Ventilador CentrÝfugo Tipo H   |            |      |
  13. +-------+-------+---------------------------------+-----------------------------------+----------+-------+-------+--------------------------------+------------+------+
  14. 6 rows in set (0.00 sec)
  15.  
  16. mysql> SELECT P.idPro, S.idSubPro, P.nomPro, S.nomSubPro, S.desSubPro, P.carPro, P.valor, P.valor, S.ruta
  17.     -> FROM
  18.     ->   productos P
  19.     ->   INNER JOIN
  20.     ->   subproducto S USING(idPro, valor)
  21.     -> WHERE P.valor='si'
  22.     -> ORDER BY P.idPro;
  23. +-------+----------+---------------------------------+--------------------------------+------------+--------+-------+-------+------+
  24. | idPro | idSubPro | nomPro                          | nomSubPro                      | desSubPro  | carPro | valor | valor | ruta |
  25. +-------+----------+---------------------------------+--------------------------------+------------+--------+-------+-------+------+
  26. |     2 |        1 | D·ctos de Ventilaci¾n de PVC    | Ducto Impelante de PVC         | dwcasdcasd |        | si    | si    |      |
  27. |     2 |        2 | D·ctos de Ventilaci¾n de PVC    | Ducto Aspirante de PVC         | asvadva    |        | si    | si    |      |
  28. |     2 |        5 | D·ctos de Ventilaci¾n de PVC    | codo para ducto de ventilaci¾n | asdvasdv   |        | si    | si    |      |
  29. |     3 |        3 | Ventiladores ElÚctricos Axiales | Ventilador Axial tipo A        |            |        | si    | si    |      |
  30. |     3 |        4 | Ventiladores ElÚctricos Axiales | Ventilador Axial tipo B        |            |        | si    | si    |      |
  31. +-------+----------+---------------------------------+--------------------------------+------------+--------+-------+-------+------+
  32. 5 rows in set (0.01 sec)
En ambos casos, lo que obtuve es lo que esperaba: los datos coincidentes de la primera tabla se repiten una vez por cada instancia diferente de la segunda. En este sentido la consulta funciona exactamente como se espera y como debe funcionar.
Así es la tabla resultado de la consulta. Siempre.

Entonces volví a tu primer post:
Cita:
Productos:
Poleras de Algodón:
Poleras Rojas
Poleras Blancas
Poleras Amarillas

Pero me esta duplicando el producto por cada subproducto, o sea:

Productos:
Poleras de Algodón:
Poleras Rojas

Poleras de Algodón:
Poleras Blancas

Poleras de Algodón:
Poleras Amarillas

Espero se entienda el problema.
Hay dos cosas distintas:
La primera lista que quieres no se obtiene solamente con la consulta. Tienes que manipular el resultado para crear esa tabla en la salida del script de PHP. No se puede hacer de otro modo porque MySQL siempre te repetirá esos primeros campos en cada instancia distinta de subproducto.
La segunda lista es la consecuencia de una condición ineficiente, porque no estabas considerando qué valor debía tener la columna "valor" en ambas tablas, y terminabas con registros que no debían usarse.
Lo que se te hacía difícil de manipular era que el ordenamiento era caótico. Algunos registros del mismo producto aparecían en posiciones incorrectas.

Sintetizando: Haz la consulta como te la paso y luego usa un for/next para recorrer la tabla, analizando en cada vuelta si cambia el valor del nombre de producto para poner el encabezado.
Eso MySQL no te lo puede hacer porque devuelve tablas, no reportes.

Tip final: Noto que estás trabajando tablas relacionadas, pero sin usar FK. Deberías considerar cambiar de tablas MyISAM a InnoDB para mantener mejor la integridad referencial
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #15 (permalink)  
Antiguo 10/06/2011, 11:05
 
Fecha de Ingreso: julio-2007
Mensajes: 287
Antigüedad: 16 años, 8 meses
Puntos: 4
De acuerdo Consulta Anidada- Interesante - Resuelto.

Tema Resuelto !!!!



acá el código por si a alguien le sirve. Y muchas gracias a las personas que colaboraron en este tema. Y a este magnífico foro.

Esta todo el material acá tablas,campos y la consulta.

Código PHP:
<?php
$sqlProd
="SELECT p.idPro,p.nomPro FROM productos p WHERE p.valor='si'";
$resProd=mysql_query($sqlProd)or die(mysql_error);
while(
$row=mysql_fetch_array($resProd))
    {
        
$idPro=$row['idPro'];
        
$nomPro=$row['nomPro'];
        echo 
"<div class='boxNomProd'><strong>$nomPro:</strong><br/>";
        
$querySubProd "SELECT s.idSubPro,s.idPro,s.nomSubPro,s.valor FROM subproducto s where s.valor='si' AND s.idPro = $idPro";
        
$resSubProd=mysql_query($querySubProd) or die(mysql_error);
        while (
$rowSubProd mysql_fetch_array($resSubProd))
    {
        
$idSubPro=$rowSubProd['idSubPro'];
        
$nomSubPro=$rowSubProd['nomSubPro'];
        
$valor=$rowSubProd['valor'];

        echo 
"<div class='textoSubPro'><a href='#?idSubPro=$idSubPro' class='link2'>$nomSubPro</a></div>";
    }
    echo 
"</div>";

    }
?>

Etiquetas: Ninguno
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 06:54.