2011-01-20 4 views
0

j'interroger une table où chaque ligne a plusieurs tags:Mysql Requête - Recherche dans une table jointe sans enregistrements filtrage

SELECT 
    user.*, 
    GROUP_CONCAT(tag.tag SEPARATOR ", ") as `tags` 
FROM 
    user 
LEFT JOIN 
    user_tag 
ON 
    user_tag.user_id = user.id 
LEFT JOIN 
    tag 
ON 
    tag.id = user_tag.tag_id 
GROUP BY 
    user.id 

Maintenant, je veux être en mesure de rechercher des utilisateurs par tags. Après avoir ajouté le où, il ressemble à ceci:

SELECT 
    user.*, 
    GROUP_CONCAT(tag.tag SEPARATOR ", ") as `tags` 
FROM 
    user 
LEFT JOIN 
    user_tag 
ON 
    user_tag.user_id = user.id 
LEFT JOIN 
    tag 
ON 
    tag.id = user_tag.tag_id 
WHERE 
    tag.tag LIKE "%engineer%" OR 
    tag.tag LIKE "%programmer%" 
GROUP BY 
    user.id 

Ceci, cependant des moyens (évidemment) que si un résultat est trouvé, la table des variables ne retourne pas tous les utilisateurs des balises plus. Ainsi, la colonne sélectionnée tags peut ressembler à "programmeur PHP", même si l'utilisateur a plus de balises.

Existe-t-il un moyen de rechercher la table jointe sans réellement limiter les résultats renvoyés sans utiliser de sous-requêtes?

+0

Il semble que vous voulez les enregistrements joints pour tous les utilisateurs où EXISTE un tag comme (par exemple) "% engineer%" ou "% programmer%". Mais bien sûr, une clause EXISTS est considérée comme une sous-requête, alors peut-être que ce n'est pas ce que vous voulez dans une réponse. Si c'était le cas, je pourrais vous montrer comment je construirais la requête. – hardmath

Répondre

0

Vous pouvez ajouter un autre JOIN avec les balises comme ceci:

SELECT 
    user.*, 
    GROUP_CONCAT(user_tags_to_return.tag SEPARATOR ", ") as `tags` 
FROM 
    user 
LEFT JOIN 
    user_tag user_tags_to_filter 
ON 
    user_tags_to_filter.user_id = user.id 
LEFT JOIN 
    tag tags_to_filter 
ON 
    tags_to_filter.id = user_tags_to_filter.tag_id 
WHERE 
    tags_to_filter.tag LIKE "%engineer%" OR 
    tags_to_filter.tag LIKE "%programmer%" 
LEFT JOIN user_tag user_tags_to_return 
ON user_tags_to_return.user_id = user.id 
LEFT JOIN tag tags_to_return 
ON tags_to_return.id = user_tags_to_return.tag_id 
GROUP BY 
    user.id 
+0

Stupide de moi. J'ai déjà essayé de rejoindre à nouveau la table des tags, mais j'aurais aussi dû rejoindre la table user_tag. – sander

1

Je suppose ici que si vous voulez éviter une sous-requête, vous pouvez utiliser une clause HAVING avec « tags », comme ceci:

SELECT 
    user.*, 
    GROUP_CONCAT(tag.tag SEPARATOR ", ") as `tags` 
FROM 
    user 
LEFT JOIN 
    user_tag 
ON 
    user_tag.user_id = user.id 
LEFT JOIN 
    tag 
ON 
    tag.id = user_tag.tag_id 
GROUP BY 
    user.id 
HAVING 
    tags LIKE "%engineer%" OR tags LIKE "%programmer%" 
+0

C'est une bonne idée. Cela fonctionnera bien dans ce cas parce que la condition utilise '% LIKE%', donc peu importe que nous comparions à un tag ou à la concaténation de tous. –

Questions connexes