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

[SOLUCIONADO] Consulta multiple a una tabla

Estas en el tema de Consulta multiple a una tabla en el foro de Mysql en Foros del Web. Hola Comunidad. Les pongo el siguiente preambulo al caso para que puedan comprender: tengo 3 tablas. tabla etiquetas tabla etiquetas_elementos tabla elementos. hasta ahi todo ...
  #1 (permalink)  
Antiguo 15/07/2013, 15:02
 
Fecha de Ingreso: abril-2011
Mensajes: 66
Antigüedad: 13 años
Puntos: 7
Consulta multiple a una tabla

Hola Comunidad.

Les pongo el siguiente preambulo al caso para que puedan comprender:

tengo 3 tablas.

tabla etiquetas
tabla etiquetas_elementos
tabla elementos.

hasta ahi todo bien, pero ahora viene la cumbia, algunos datos:

Código MySQL:
Ver original
  1. -- phpMyAdmin SQL Dump
  2. -- version 3.4.5deb1
  3. -- http://www.phpmyadmin.net
  4. --
  5. -- Servidor: localhost
  6. -- Tiempo de generación: 15-07-2013 a las 16:42:52
  7. -- Versión del servidor: 5.1.67
  8. -- Versión de PHP: 5.3.6-13ubuntu3.9
  9.  
  10. SET FOREIGN_KEY_CHECKS=0;
  11. SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
  12. SET time_zone = "+00:00";
  13.  
  14. --
  15. -- Base de datos: `test`
  16. --
  17.  
  18. -- --------------------------------------------------------
  19.  
  20. --
  21. -- Estructura de tabla para la tabla `elementos`
  22. --
  23.  
  24. CREATE TABLE IF NOT EXISTS `elementos` (
  25.   `id_interno` int(10) unsigned NOT NULL AUTO_INCREMENT,
  26.   `nombre_elemento` varchar(255) COLLATE utf8_spanish_ci DEFAULT NULL,
  27.   `descripcion_elemento` varchar(255) COLLATE utf8_spanish_ci DEFAULT NULL,
  28.   PRIMARY KEY (`id_interno`)
  29. ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci AUTO_INCREMENT=5 ;
  30.  
  31. --
  32. -- Volcado de datos para la tabla `elementos`
  33. --
  34.  
  35. INSERT INTO `elementos` (`id_interno`, `nombre_elemento`, `descripcion_elemento`) VALUES
  36. (1, 'teclado', 'teclado de computador'),
  37. (2, 'mesa comedor', 'mesa cuadrada de 4 asientos'),
  38. (3, 'silla comedor', 'silla color cafe'),
  39. (4, 'set cuchillos', 'cuchillos de cocina');
  40.  
  41. -- --------------------------------------------------------
  42.  
  43. --
  44. -- Estructura de tabla para la tabla `etiquetas`
  45. --
  46.  
  47. CREATE TABLE IF NOT EXISTS `etiquetas` (
  48.   `id_interno` int(10) unsigned NOT NULL AUTO_INCREMENT,
  49.   `descripcion` varchar(255) COLLATE utf8_spanish_ci DEFAULT NULL,
  50.   PRIMARY KEY (`id_interno`)
  51. ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci AUTO_INCREMENT=6 ;
  52.  
  53. --
  54. -- Volcado de datos para la tabla `etiquetas`
  55. --
  56.  
  57. INSERT INTO `etiquetas` (`id_interno`, `descripcion`) VALUES
  58. (1, 'COMEDOR'),
  59. (2, 'LIVING'),
  60. (3, 'BANO'),
  61. (4, 'COCINA'),
  62. (5, 'DORMITORIO');
  63.  
  64. -- --------------------------------------------------------
  65.  
  66. --
  67. -- Estructura de tabla para la tabla `etiqueta_elemento`
  68. --
  69.  
  70. CREATE TABLE IF NOT EXISTS `etiqueta_elemento` (
  71.   `id_interno` int(10) unsigned NOT NULL AUTO_INCREMENT,
  72.   `id_elemento` int(10) unsigned DEFAULT NULL,
  73.   `id_etiqueta` int(10) unsigned DEFAULT NULL,
  74.   PRIMARY KEY (`id_interno`)
  75. ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci AUTO_INCREMENT=7 ;
  76.  
  77. --
  78. -- Volcado de datos para la tabla `etiqueta_elemento`
  79. --
  80.  
  81. INSERT INTO `etiqueta_elemento` (`id_interno`, `id_elemento`, `id_etiqueta`) VALUES
  82. (1, 1, 2),
  83. (2, 1, 5),
  84. (3, 2, 4),
  85. (4, 3, 4),
  86. (5, 2, 2);
  87. SET FOREIGN_KEY_CHECKS=1;

La idea es que de acuerdo a los datos publicados, la consulta sea capaz de obtenerme el(los) elementos que contengan la(las) etiquetas que yo especifique.

Estuve probando con lo siguiente, pero al parecer no me funciono.

Código MySQL:
Ver original
  1. *
  2. FROM etiquetas_elementos ee
  3. LEFT JOIN etiquetas eti ON eti.id_interno = ee.id_etiqueta
  4. LEFT JOIN elementos e ON e.id_interno = ee.id_elemento
  5. eti.descripcion = 'COCINA' AND eti.descripcion = 'LIVING'
  6.  
  7. //tambien habia probado con IN
  8.  
  9. .....
  10. eti.descripcion IN ('COCINA' ,'LIVING')

Nota: este ejemplo es solo para explicar el funcionamiento del problema que tengo, pero no es que tenga asi las bases de datos en realidad.

Si alguien aporta alguna idea, se lo agradezco.
  #2 (permalink)  
Antiguo 15/07/2013, 15:44
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 meses
Puntos: 447
Respuesta: Consulta multiple a una tabla

Hola max_mouse699:

Este tipo de consultas es bastante común y lo hemos respondido muchas veces en el foro, hay varias formas de hacerlo, la más común es con GROUP BY y HAVING:

Observa el ejemplo:

Código MySQL:
Ver original
  1. mysql> SELECT * FROM etiquetas;
  2. +------------+-------------+
  3. | id_interno | descripcion |
  4. +------------+-------------+
  5. |          1 | COMEDOR     |
  6. |          2 | LIVING      |
  7. |          3 | BANO        |
  8. |          4 | COCINA      |
  9. |          5 | DORMITORIO  |
  10. +------------+-------------+
  11. 5 rows in set (0.00 sec)
  12.  
  13. mysql> SELECT * FROM etiqueta_elemento;
  14. +------------+-------------+-------------+
  15. | id_interno | id_elemento | id_etiqueta |
  16. +------------+-------------+-------------+
  17. |          1 |           1 |           2 |
  18. |          2 |           1 |           5 |
  19. |          3 |           2 |           4 |
  20. |          4 |           3 |           4 |
  21. |          5 |           2 |           2 |
  22. +------------+-------------+-------------+
  23. 5 rows in set (0.00 sec)

Puedes poner una condición WHERE para filtrar las características que te interesan utilizar la función COUNT para saber cuántas características tiene cada grupo, es decir, algo como esto:

Código MySQL:
Ver original
  1. mysql> SELECT id_elemento, COUNT(*) total
  2.     -> FROM etiqueta_elemento EE
  3.     -> INNER JOIN etiquetas E ON EE.id_etiqueta = E.id_interno
  4.     -> WHERE e.descripcion IN ('COCINA' ,'LIVING')
  5.     -> GROUP BY id_elemento;
  6. +-------------+-------+
  7. | id_elemento | total |
  8. +-------------+-------+
  9. |           1 |     1 |
  10. |           2 |     2 |
  11. |           3 |     1 |
  12. +-------------+-------+
  13. 3 rows in set (0.00 sec)

de esta consulta se desprende que el id_elemento = 1 sólo tiene uno de las dos características (LIVING), el id_elemento = 2 tiene las dos características (COCINA, LIVING) y el id_elemento = 3 tiene una sola (COCINA)... por lo tanto sólo el id_elemento = cumple con ambas características a la vez... lo único que tienes que hacer es agregar la cláusula HAVING al final de la consulta:

Código MySQL:
Ver original
  1. mysql> SELECT id_elemento, COUNT(*) total
  2.     -> FROM etiqueta_elemento EE
  3.     -> INNER JOIN etiquetas E ON EE.id_etiqueta = E.id_interno
  4.     -> WHERE e.descripcion IN ('COCINA' ,'LIVING')
  5.     -> GROUP BY id_elemento
  6.     -> HAVING COUNT(*) = 2;
  7. +-------------+-------+
  8. | id_elemento | total |
  9. +-------------+-------+
  10. |           2 |     2 |
  11. +-------------+-------+
  12. 1 row in set (0.00 sec)

Con esta consulta puedes filtrar la información que necesites.

Haz la prueba, utiliza la herramienta de búsqueda del foro para encontrar otros post semejantes, si continuas con problemas postea algo de lo que intentaste hacer y con gusto te ayudamos a afinar la consulta.

Saludos
Leo.
  #3 (permalink)  
Antiguo 15/07/2013, 16:11
 
Fecha de Ingreso: abril-2011
Mensajes: 66
Antigüedad: 13 años
Puntos: 7
Respuesta: Consulta multiple a una tabla

Cita:
Este tipo de consultas es bastante común y lo hemos respondido muchas veces en el foro, hay varias formas de hacerlo, la más común es con GROUP BY y HAVING:

..........

Haz la prueba, utiliza la herramienta de búsqueda del foro para encontrar otros post semejantes, si continuas con problemas postea algo de lo que intentaste hacer y con gusto te ayudamos a afinar la consulta.
Gracias leonardo_josue por tu respuesta. La verdad es que no sabia como expresarme a la hora de estar creando el tema, también intente mas de una hora buscando el google, pero como dije, nose como expresarme a lo que necesito.

Tampoco sabia del uso de HAVING, sabia que existía, pero no sabia como trabaja, como se utiliza.

Te agradezco, pero ahora me surge otro problema, lo que pasa es que en la condición de búsqueda por los criterios de 'COCINA' y 'LIVING', estos criterios pueden ser dos o mas criterios, por lo cual necesitaría como algo que fuera automático, o sea que, dependiendo de la cantidad de condiciones que coloque, siempre me tome la de mayor cantidad.

Pero..... espera, se me ocurre algo: Puede ser algo parecido a esto:

Código MySQL:
Ver original
  1. mysql> SELECT id_elemento, COUNT(*) total
  2.     -> FROM etiqueta_elemento EE
  3.     -> INNER JOIN etiquetas E ON EE.id_etiqueta = E.id_interno
  4.     -> WHERE e.descripcion IN ('COCINA' ,'LIVING')
  5.     -> GROUP BY id_elemento
  6.     -> HAVING MAX(COUNT(*));
  7. +-------------+-------+
  8. | id_elemento | total |
  9. +-------------+-------+
  10. |           2 |     2 |
  11. +-------------+-------+
  12. 1 row IN SET (0.00 sec)

Pero, no me resulta, me arrojo un error, pero la idea era mas o menos esa, se puede algo parecido ?.

PD: Como logras obtener ese tipo de consultas (me refiero a la escritura de la consulta) que solo la arroja la consola de mysql, y poder pegarla en este foro ?

Saludos
  #4 (permalink)  
Antiguo 16/07/2013, 08:06
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 meses
Puntos: 447
Respuesta: Consulta multiple a una tabla

Hola de nuevo:

El que no conozcas algo tan básico como el HAVING me da mucho que pensar... creo que deberías tomarte el tiempo para leer cualquier libro de SQL para principiantes, pues hay conceptos que veo que no dominas y eso te está complicando la existencia...

Para obtener el registro que tenga el mayor "total", simplemente ordena tus registros por este campo y obtén el primer registro con LIMIT 1:

Código MySQL:
Ver original
  1. mysql> SELECT id_elemento, COUNT(*) total
  2.     -> FROM etiqueta_elemento EE
  3.     -> INNER JOIN etiquetas E ON EE.id_etiqueta = E.id_interno
  4.     -> WHERE e.descripcion IN ('COCINA' ,'LIVING')
  5.     -> GROUP BY id_elemento
  6.     -> ORDER BY total DESC
  7.     -> LIMIT 1;
  8. +-------------+-------+
  9. | id_elemento | total |
  10. +-------------+-------+
  11. |           2 |     2 |
  12. +-------------+-------+
  13. 1 row in set (0.00 sec)

De esta manera ya no necesitarás el HAVING.

En cuanto a la PostData, las consultas las ejecuto desde línea de comando de MySQL, de esta manera puedo copiar la consulta y los resultados que se presentan.

Saludos
Leo.
  #5 (permalink)  
Antiguo 17/07/2013, 07:34
 
Fecha de Ingreso: abril-2011
Mensajes: 66
Antigüedad: 13 años
Puntos: 7
Respuesta: Consulta multiple a una tabla

Hola.

Cita:
El que no conozcas algo tan básico como el HAVING me da mucho que pensar... creo que deberías tomarte el tiempo para leer cualquier libro de SQL para principiantes, pues hay conceptos que veo que no dominas y eso te está complicando la existencia...
Podrías tu recomendarme un libro, puesto que si desde tu punto de vista es algo básico que tengo que dominar, pues me gustaría si puedes darme el consejo de que otro tipo de conceptos son los básicos que tengo que dominar. Estuve buscando en internet, pero los libros que son para principiantes solo hablan temas y sentencias que ya conozco y domino.

Si quieres, me lo puedes enviar en un MP, o de lo contrario publicarlo.

En cuanto a tu solución, me resulto super bien, por lo tanto puedo dar el tema como solucionado, porque el problema ya se soluciono.

Te agradezco tu tiempo.
Saludos
Max

Etiquetas: insert, join, php, select, sql, tabla
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 21:53.