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

query para buscar varios tags de usuario

Estas en el tema de query para buscar varios tags de usuario en el foro de Mysql en Foros del Web. Hola, Tengo una base de datos con 3 tablas, usuarios, tags, usuario_tags la tabla usuario_tags relaciona los usuario con los tags, cada usuario puede tener ...
  #1 (permalink)  
Antiguo 19/09/2011, 09:52
 
Fecha de Ingreso: marzo-2008
Mensajes: 99
Antigüedad: 16 años, 8 meses
Puntos: 0
Pregunta query para buscar varios tags de usuario

Hola,
Tengo una base de datos con 3 tablas, usuarios, tags, usuario_tags
la tabla usuario_tags relaciona los usuario con los tags, cada usuario puede tener varios tags.
La estructura es:

usuario:
uid
nombre

Tags:
tid
nombre

usuario_tags:
usuario_id
tags_id


Quiero poder filtrar todos los usuarios que tengan por ejemplo el tag 3 y tag 4. Por ejemplo en la url pongo /autos/usados y el resultado tiene que mostrar todos los usuarios con dichos tags.

Espero que se entienda el problema y alquien me pueda dar una solución.

Gracias.
  #2 (permalink)  
Antiguo 19/09/2011, 14:32
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 11 meses
Puntos: 447
Respuesta: query para buscar varios tags de usuario

Hola carlosdanielmou:

No estoy seguro de si entendí correctamente cual es el problema, pero checa este script a ver si es más o menos lo que necesitas:

Código MySQL:
Ver original
  1. mysql> CREATE TABLE usuario (uid INT, nombre VARCHAR(10));
  2. Query OK, 0 rows affected (0.11 sec)
  3.  
  4. mysql> INSERT INTO usuario VALUES (1, 'uno'), (2, 'dos'), (3, 'tres');
  5. Query OK, 3 rows affected (0.01 sec)
  6. Records: 3  Duplicates: 0  Warnings: 0
  7.  
  8. mysql> SELECT * FROM usuario;
  9. +------+--------+
  10. | uid  | nombre |
  11. +------+--------+
  12. |    1 | uno    |
  13. |    2 | dos    |
  14. |    3 | tres   |
  15. +------+--------+
  16. 3 rows in set (0.00 sec)
  17.  
  18. mysql> CREATE TABLE tags (tid INT, nombre VARCHAR(10));
  19. Query OK, 0 rows affected (0.08 sec)
  20.  
  21. mysql> INSERT INTO tags VALUES (1, 'autos'), (2, 'usados'), (3, 'nuevos');
  22. Query OK, 3 rows affected (0.03 sec)
  23. Records: 3  Duplicates: 0  Warnings: 0
  24.  
  25. mysql> SELECT * FROM tags;
  26. +------+--------+
  27. | tid  | nombre |
  28. +------+--------+
  29. |    1 | autos  |
  30. |    2 | usados |
  31. |    3 | nuevos |
  32. +------+--------+
  33. 3 rows in set (0.00 sec)
  34.  
  35. mysql> CREATE TABLE usuario_tags (usuario_id INT, tags_id INT);
  36. Query OK, 0 rows affected (0.08 sec)
  37.  
  38. mysql> INSERT INTO usuario_tags VALUES (1, 1), (1, 2), (1, 3), (2, 2),
  39.     -> (2, 3), (3, 1), (3, 2);
  40. Query OK, 7 rows affected (0.05 sec)
  41. Records: 7  Duplicates: 0  Warnings: 0
  42.  
  43. mysql> SELECT * FROM usuario_tags;
  44. +------------+---------+
  45. | usuario_id | tags_id |
  46. +------------+---------+
  47. |          1 |       1 |
  48. |          1 |       2 |
  49. |          1 |       3 |
  50. |          2 |       2 |
  51. |          2 |       3 |
  52. |          3 |       1 |
  53. |          3 |       2 |
  54. +------------+---------+
  55. 7 rows in set (0.00 sec)
  56.  
  57. mysql> SELECT T1.* FROM usuario T1 INNER JOIN
  58.     -> (SELECT usuario_id FROM usuario_tags
  59.     -> WHERE tags_id IN (1, 2) GROUP BY usuario_id
  60.     -> HAVING COUNT(usuario_id) = 2
  61.     -> ) T2 ON T1.uid = T2.usuario_id;
  62. +------+--------+
  63. | uid  | nombre |
  64. +------+--------+
  65. |    1 | uno    |
  66. |    3 | tres   |
  67. +------+--------+
  68. 2 rows in set (0.00 sec)

Todo el problema se resuelve en el select interno marcado como T2. Para el ejemplo estoy buscando aquellos usuarios que tengan los tags 1 y 2.

Código:
tags_id IN (1, 2)
El truco está en agrupar por usuario_id y preguntar por aquellos que tengan un HAVING COUNT = 2

Código:
GROUP BY usuario_id HAVING COUNT(usuario_id) = 2
para el caso del usuario 2, su COUNT sería de 1 (pues sólo tiene el tag 2), por lo tanto no entra dentro del filtrado.

Dale un vistazo para ver si es lo que necesitas, y si continuas con problemas pon algunos datos de ejemplo en tus tablas, para poder tratar de ayudarte.

Saludos
Leo.
  #3 (permalink)  
Antiguo 20/09/2011, 07:45
 
Fecha de Ingreso: marzo-2008
Mensajes: 99
Antigüedad: 16 años, 8 meses
Puntos: 0
Respuesta: query para buscar varios tags de usuario

Hola Leo, gracias por la ayuda, eso era justo lo que estaba buscando. Muy bien explicado.

Yo estuve buscando un poco por G! y había encntrado esta otra query que no la entiendo del todo pero decian que era la mejor forma por performance ya que hacer having tarda un poco más.
Código SQL:
Ver original
  1. SELECT *
  2.             FROM tags t1 CROSS JOIN tags t2 CROSS JOIN tags t3
  3.             INNER JOIN tags_usuario tu1
  4.             ON t1.id = tu1.tags_id
  5.             INNER JOIN tags_usuario tu2
  6.             ON tu1.usuario_id = tu2.usuario_id
  7.             AND tu2.tags_id = t2.id
  8.             INNER JOIN tags_usuario tu3
  9.             ON tu2.usuario_id = tu3.usuario_id
  10.             AND tu3.tags_id = t3.id
  11.             INNER JOIN usuario u ON u.id = tu3.usuario_id
  12.             WHERE t1.id = $idTag1
  13.             AND t2.id = $idTag2
  14.             AND t3.id = $idTag3;

La base de datos va a tener aproximadamente 2 millones de usuarios y 300.000 tags y por cada usuario unos 10-15 tags por lo que la performance me importa bastante. Pero también me importa entender lo que hago así que voy a ver cual de las dos opciones uso.

Saludos y Gracias....

Etiquetas: query, tabla, tags, usuarios
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 01:54.