Comunidad de diseño web y desarrollo en internet online

MySQL > Filtrar una tabla con otra pero usando 2 condiciones

Citar            
MensajeEscrito el 11 Oct 2009 07:20 pm
Creo que el título no ayuda mucho a entender mi pregunta :S

El tema es así:

Tengo una tabla con PRODUCTOS, otra con ETIQUETAS y una intermedia PRODUCTOS_ETIQUETAS donde se almacenan la relacion entre cada producto y sus etiquetas, algo así:
PRODUCTOS: id, titulo
ETIQUETAS: id, nombre
PRODUCTOS_ETIQUETAS : producto_id, etiqueta_id

Bien, lo que yo quiero hacer es un listado de productos relacionado a varias etiquetas. Para listar los productos de una sola etiqueta no hay problema, con un JOIN se resuelve:

Código MySQL :

SELECT *
FROM productos
JOIN productos_etiquetas ON productos_etiquetas.producto_id = producto.id
WHERE productos_etiquetas.producto_id = 30

"30" sería el id de la etiqueta que me interesa filtrar
El problema es al intentar filtrar por dos etiquetas, supongamos que quiero listar los productos que tengan las etiquetas 30 y 2

Lo he resuelto pero intuyo que hay mejores soluciones.

Código MySQL :

SELECT productos.id, productos.titulo,  COUNT(*) AS count
FROM (productos_etiquetas)
JOIN productos ON productos_etiquetas.producto_id=productos.id
WHERE condicionxxx = xxx
AND productos_etiquetas.etiqueta_id IN ('30', '2') 
GROUP BY productos_etiquetas.producto_id HAVING count > 1
ORDER BY productos.titulo ASC
LIMIT 3  


Esto funciona. Básicamente lo que hace es filtrar por las etiquetas que me interesa y agrupar por el id del producto, entonces si hay mas de 1 significa que tiene las 2 etiquetas.

No me gusta para nada esta solución, pero llegué hasta aquí despues de darle unas cuantas vueltas :S

Además tiene el problema que si quiero contar la cantidad de resultados no puedo, porque el COUNT me indica según el GROUP... asi que menos todavía.

¿Hay alguna otra manera de hacer esto? Quizás haya una manera "mágica" y tonta que se me está pasando...

Por Josepzin

208 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 11 Oct 2009 10:39 pm

Código MySQL :

SELECT *  -- debes escribir los campos a mostrar, supongo que el uso de * lo hiciste solo a modo de ejemplo 
FROM productos p -- te recomiendo usar alias 
INNER JOIN productos_etiquetas pe ON pe.producto_id = p.id  -- define que tipo de join quieres usar left o inner 
WHERE pe.producto_id = 30 OR pe.producto_id = 2 --  usando OR para ver otras posibles igualdades 



[spam] este tip también te puede ayudar http://www.cristalab.com/tips/consulta-sql-a-mas-de-dos-tablas-con-join-c77632l [/spam]

Por Inyaka

Claber

3176 de clabLevel

9 tutoriales
2 articulos

Genero:Masculino   Desarrollador de GAIA

Programador y fotógrafo

firefox
Citar            
MensajeEscrito el 12 Oct 2009 06:42 am
Gracias por responder Inyaka :)

Sobre el SELECT *, sí, es para el ejemplo.

Sobre tu código, el tema es que leería los productos con etiqueta 30 OR 2, y yo necesito que sea 30 AND 2
Y ese es el problema, porque poniendo AND el resultado es 0 productos.

Por Josepzin

208 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 12 Oct 2009 07:14 am
entonces en ese parte puedes seguir con el IN('30','02') hay si te sirve mas esta funcion

Por talcual

686 de clabLevel



 

Colombia

firefox
Citar            
MensajeEscrito el 12 Oct 2009 07:53 am
talcual: es igual, el WHERE IN 30,10 hace lo mismo que 30 OR 10

Por Josepzin

208 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 12 Oct 2009 03:06 pm
He publicado la pregunta también en Forosdelweb, creo que mejor explicada :D

http://www.forosdelweb.com/f87/filtrar-tabla-con-otra-usando-dos-condiciones-743280/#post3119790

Por Josepzin

208 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 12 Oct 2009 03:37 pm
aun no te entiendo cual es el problema, digamos que tienes las etiquetas 2 (ferreteria)y 30(ropa) y los siguientes productos: con sus respectivos ID


  1. alicate
  2. clavo
  3. tornillo
  4. zapato de seguridad
  5. overol
  6. camisa


ademas la tabla de relación


  • 1 a 2
  • 2 a 2
  • 3 a 2
  • 4 a 2
  • 5 a 2
  • 4 a 30
  • 5 a 30
  • 6 a 30



teniendo estas tablas ¿que resultado quieres obtener?

Por Inyaka

Claber

3176 de clabLevel

9 tutoriales
2 articulos

Genero:Masculino   Desarrollador de GAIA

Programador y fotógrafo

firefox
Citar            
MensajeEscrito el 12 Oct 2009 04:01 pm
Yo quiero saber qué productos tienen asignada la etiqueta Ferretería y Ropa, así que teniendo en cuenta tus datos el resultado de mi consulta sería:
4: zapato de seguridad
5: overol


Que son los dos productos que pertenecen/tienen Ferretería y Ropa

Espero que se entienda :)

Por Josepzin

208 de clabLevel



 

España

chrome
Citar            
MensajeEscrito el 12 Oct 2009 07:31 pm
entonces puedes usar el in o el where con el or no veo cual es el complique realiza la relacion igual que inyaka no veo cual sea el problema :-D

Por talcual

686 de clabLevel



 

Colombia

firefox
Citar            
MensajeEscrito el 12 Oct 2009 07:49 pm
Es que si es OR o IN el resultado es: 1, 2, 3, 4 y 5, o sea todos los productos que tienen etiquetas 30 y 2. Y yo sólo necesito los que tienen ambas etiquetas, no solo una de ellas. ¿no?

Por Josepzin

208 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 12 Oct 2009 09:13 pm
haaa ahora si pero para eso debes usar un and no un in ni or con el and seleccionas las que tienen ambas etiquetas :-D sera que ese es tu problema

Por talcual

686 de clabLevel



 

Colombia

firefox
Citar            
MensajeEscrito el 12 Oct 2009 09:15 pm
Ojalá fueta tan simple, el tema es que seleccionando con AND no trae ni uno ni el otro, porque parece que compara de a una etiqueta por vez, asi entonces nunca es ambas al mismo tiempo... :?

Por Josepzin

208 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 12 Oct 2009 11:01 pm
usa subconsultas

Por xcom

Claber

530 de clabLevel



 

firefox
Citar            
MensajeEscrito el 13 Oct 2009 04:40 am
bien, asi si se entendio la pregunta y me pude abocar a responderla, no adivinarla XD

mira, tuve que experimentar un poco, asi es que tome las tablas que cree en mi tutorial que te di mas arriba lo nuevo es que use la propiedad HAVING dentro del GROUP BY esta propiedad se refiere a las condiciones del GROUP BY

Código MySQL :

SELECT * FROM usuarios u
INNER JOIN us2bod ub ON  u.`us_id`= ub.`us_id`
INNER JOIN bodegas b ON  b.`bod_id` = ub.`bod_id`
GROUP BY  u.`us_id` HAVING COUNT(b.`bod_id`)>1

Por Inyaka

Claber

3176 de clabLevel

9 tutoriales
2 articulos

Genero:Masculino   Desarrollador de GAIA

Programador y fotógrafo

firefox
Citar            
MensajeEscrito el 13 Oct 2009 04:49 am
harggg no era eso, :P disculpa, volveré a vuelta de comerciales

Por Inyaka

Claber

3176 de clabLevel

9 tutoriales
2 articulos

Genero:Masculino   Desarrollador de GAIA

Programador y fotógrafo

firefox
Citar            
MensajeEscrito el 13 Oct 2009 05:30 am
efectivamente no quedo otra que crear una sub consulta :P

Código MySQL :

SELECT u.`us_id`, u.`us_nombre`FROM usuarios u
WHERE  (SELECT ub.`us_id` FROM us2bod ub WHERE ub.`bod_id` = 3 AND ub.`us_id` =  u.`us_id`)
AND (SELECT ub.`us_id` FROM us2bod ub WHERE ub.`bod_id` = 1 AND ub.`us_id` =  u.`us_id`)

Por Inyaka

Claber

3176 de clabLevel

9 tutoriales
2 articulos

Genero:Masculino   Desarrollador de GAIA

Programador y fotógrafo

firefox
Citar            
MensajeEscrito el 13 Oct 2009 11:31 am
Gracias por responder, nunca he usado las subconsultas. Voy a probar ese ejemplo a ver si me funciona, luego cuento como me fue

Por Josepzin

208 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 13 Oct 2009 11:46 am
¡GENIAL!, va perfecto y me parece una buena solución :)

Para completar el tema, publico la respuesta siguiendo mi esquema de datos:

Código MySQL :

SELECT p.id, p.titulo
FROM productos p 
WHERE  
   (SELECT pe.etiqueta_id FROM productos_etiquetas pe WHERE pe.etiqueta_id = 2 AND pe.producto_id=p.id) 
   AND 
   (SELECT pe.etiqueta_id FROM productos_etiquetas pe WHERE pe.etiqueta_id = 30 AND pe.producto_id=p.id)


Nunca había usado tampoco las abreviaturas, interesantes. Al usar CodeIgniter dudo mucho que las aplique, pero es un buen recurso.

Por Josepzin

208 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 13 Oct 2009 04:21 pm
yo uso codeigniter y la verdad es que las consultas las sigo haciendo a mano (y por tanto con alias)

Por Inyaka

Claber

3176 de clabLevel

9 tutoriales
2 articulos

Genero:Masculino   Desarrollador de GAIA

Programador y fotógrafo

firefox
Citar            
MensajeEscrito el 13 Oct 2009 04:39 pm
Muy bien, otro CI :)

A mi me resulta muy práctico usar el sistema de CI db->where(), etc. Supongo que será cuestión de práctica con el SQL

Por Josepzin

208 de clabLevel



 

España

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.