2015-08-21 2 views
3

Je rencontre un problème avec la recherche de lignes de base de données connexes qui ne sont pas spécifiquement liées. Disons que nous avons 5 tables.Recherche d'une liste dans une liste

Products 
Id | name 

Product_tags 
Id | product_id | tag_id 

Tags 
Id | name 

Blog 
Id | name 

Blog_tags 
Id | blog_id | tag_ids 

Alors ce que je fais est que je prends un produit, avec cette saisir les balises de ce produit a par la table Product_tags. Dis que je reçois quelque chose comme ça.

Product 101 
Tags 123,124,125,126 

Maintenant j'ai cette page de produit. La chose est, maintenant je veux trouver un blog s'il correspond à ce produit, mais il n'a pas besoin d'avoir tous les tags que ce produit a, le produit a juste besoin d'avoir tout ce blog a. Donc, si le blog a des balises 124 et 126, il doit correspondre. Actuellement, je sauvegarde tous les tags d'un blog sur une ligne (séparés par des virgules) mais cela peut être changé pour économiser 1 tag par ligne si nécessaire. Si c'était inversé je pourrais le faire mais j'ai besoin de vérifier une liste partielle dans une table différente.

Product 101 
Tags 123,124,125,126 

Should find 
Blog 201 
Tags 124,126 

But not 
Blog 202 
Tags 120,124 

J'ai essayé quelques façons, mais je ne pouvais pas trouver un moyen de faire ce travail, ma tentative la plus proche était un inverse comme comme celui-ci.

select * from Blog_tags where "'".implode(",",$tagIds)."'" LIKE concat("%", tag_ids, "%") 

Ce tri de travail mais pas lorsque le produit avait 1,2,3 et le blog n'avait 1,3.

+0

Si je comprends votre problème correctement: vous avez une liste des balises (de produits), et que vous voulez trouver les blogs dont les étiquettes sont ** ** tous inclus dans ce liste, et qui ont ** au moins ** une étiquette? Est-ce exact? – rlanvin

+0

Oui. Tous les tags de blog doivent être présents dans la liste des tags de produit, mais la liste des tags de produit peut contenir des tags supplémentaires qui ne sont pas présents dans la liste des blogs. – xStoryTeller

Répondre

1

Ceci est non testé et seulement de la mémoire, alors n'hésitez pas à commenter et dites-moi si cela ne fonctionne pas.

Tout d'abord, normaliser votre liste de tags, n'utilisez pas de chaîne séparée par des virgules. Vous avez dit que cela pourrait être changé, donc je vais travailler pour supposer que c'est une ligne par étiquette, et le nom de la colonne est tag_id.

LET début de blogs en trouvant les ayant quelques-unes des balises de vous produit 101.

SELECT * 
FROM Blog 
JOIN Blog_tags ON Blog.Id = Blog_tags.blog_id 
WHERE tag_id IN (123,124,125,126) 
GROUP BY Blog.Id 

Maintenant, cette requête comprendra également des blogs qui ont des étiquettes pas dans cette liste. Nous devons donc les enlever. Je pense que quelque chose comme ça pourrait fonctionner:

SELECT * 
FROM (
    SELECT Blog.id as blogId 
    FROM Blog 
    JOIN Blog_tags ON Blog.Id = Blog_tags.blog_id 
    WHERE tag_id IN (123,124,125,126) 
    GROUP BY Blog.Id 
) as Blog_filtered 
LEFT JOIN Blog_tags ON Blog_filtered.blogId = Blog_tags.blog_id AND Blog_tags.tag_id NOT IN (123,124,125,126) 
WHERE Blog_tags.id IS NULL 
GROUP BY Blog_filtered.blogId 
+0

Cela a fonctionné avec de légères modifications. Je les ai inclus dans votre réponse. – xStoryTeller

+0

@xStoryTeller Lors de votre modification, vous sélectionnez uniquement l'ID du blog. Êtes-vous sûr que vous n'avez pas besoin de plus (comme le nom)? – rlanvin