2010-11-11 9 views
0

Ceci est relatif à mysql query with AND, OR and NOT et aussi mysql has all values j'ai résolu le AND partie du problème, mais maintenant je dois aussi maintenant pour résoudre le OR et le NOT.complexe MySQL rejoint

Juste pour confirmer la déclaration ci-dessous me donne tous les articles qui ont chaque thème 1, 2 et 3

SELECT x.* 
FROM Article x INNER JOIN 
(SELECT t.article_id, COUNT(t.article_id) 
    FROM articleTopics t 
    WHERE t.topic_id IN ('1','2','3') 
    GROUP BY t.article_id 
    HAVING COUNT(t.article_id)>=3 
    ORDER BY COUNT(t.article_id) DESC 
    LIMIT 0,100) AS ilv 
ON x.id=ilv.article_id 

Ce que je suis en train de faire est d'ajouter quelque chose à la requête qui exclurait tous les articles qui sont aussi associés aux sujets 4 et 5.: NOT

Je voudrais également ajouter les articles qui ont des sujets 6, ou 7 tant qu'ils correspondent aux contraintes précédentes.

E.g.

SELECT all Articles where the articles has 
    all the following topics (1,2,3) #AND 
AND 
    none of the following topics (4,5) #NOT 
AND 
    may have any of the following topics(6,7) #OR 

J'espère que cela a du sens!

+2

Je ne vois pas le point de chercher 6 & 7 si l'exigence est qu'un article doit d'abord être associé à 1/2/3. Sonne comme ARTICLETOPCS est une table many-to-many, donc tout ce qui touche à 1/2/3 sera sélectionné - y compris ceux avec des liens supplémentaires à 6 et/ou 7. –

+0

de sorte que vous avez besoin d'articles où (sujet dans (1, 2, 3) et non sujet dans (4, 5)) ou sujet dans (6, 7)? – Sam

+0

On dirait qu'une ERD serait utile pour celle-ci ... – Sonny

Répondre

0

C'est ce que j'ai fini avec:

SELECT x.* 
FROM Article x INNER JOIN 
(SELECT t.article_id, COUNT(t.article_id) 
    FROM articleTopics t 
    WHERE t.topic_id IN ('1','2','3') 
    AND NOT EXISTS (
     SELECT 1 
     FROM articleTopics 
     WHERE article_id = t.article_id 
     AND entity_id IN ('4','5')) 
    GROUP BY t.article_id 
    HAVING COUNT(t.article_id)>=3 
    ORDER BY COUNT(t.article_id) DESC 
    LIMIT 0,100) AS ilv 
ON x.id=ilv.article_id 
LEFT JOIN articleTopics at ON at.article_id = x.id 
WHERE ae_topic_id IN ('6','7') 

Cela dit tous les articles doivent contenir tous les sujets 1,2,3 et atleast 1 de 6 ou 7 mais n'incluez jamais 4 ou 5

Nous vous remercions de votre aide.

0

Je voudrais utiliser la fonction EXISTS comme:

SELECT ... 
FROM Article a 
WHERE EXISTS (SELECT topic_id FROM articleTopics t WHERE t.article_id = a.article_id AND topic_id = 1) 
    AND EXISTS (SELECT topic_id FROM articleTopics t WHERE t.article_id = a.article_id AND topic_id = 2) 
    AND EXISTS (SELECT topic_id FROM articleTopics t WHERE t.article_id = a.article_id AND topic_id = 3) 
    AND NOT EXISTS (SELECT topic_id FROM articleTopics t WHERE t.article_id = a.article_id AND topic_id = 4) 
    AND NOT EXISTS (SELECT topic_id FROM articleTopics t WHERE t.article_id = a.article_id AND topic_id = 5) 
    AND (EXISTS (SELECT topic_id FROM articleTopics t WHERE t.article_id = a.article_id AND topic_id = 6) 
    OR EXISTS (SELECT topic_id FROM articleTopics t WHERE t.article_id = a.article_id AND topic_id = 7)) 
+0

Cela voudrait dire que l'article doit être dans les rubriques 1,2 ET 3. Non OU. Je ne pense pas que ce soit ce qu'il cherche. – Cfreak

+0

@cFreak Je cherche des articles qui doivent être dans tous les 3 sujets – Lizard

+0

@Lizard: vous devriez alors clarifier la question originale. IN() est équivalent à OU, donc votre logique AND ne fonctionne pas. – Cfreak

0

On dirait que ce serait beaucoup plus simple d'utiliser un JOIN régulier que d'utiliser un sous-. Devrait être plus rapide aussi.

SELECT * FROM articles JOIN articleTopics USING(article_id) 
WHERE topic_id IN(1,2,3) AND topic_id NOT IN (4,5) GROUP BY article_id; 

Je ne vois pas pourquoi vous devez spécifier 6 et 7. À moins que vous dites si elle a 6 ou 7 les autres règles ne comptent pas. Dans ce cas, vous pouvez faire:

SELECT * FROM articles JOIN articleTopics USING(article_id) 
    WHERE (topic_id IN(1,2,3) AND topic_id NOT IN (4,5)) OR topic_id IN(6,7) GROUP BY article_id; 
+0

topic_id IN (1,2,3) retournerait des articles qui ont un de ces sujets, j'ai besoin où il a tous ces sujets. Pareil avec PAS DANS – Lizard