2011-04-27 9 views
2

Je me demandais si quelqu'un ici pouvait m'aider avec un problème que j'ai. J'essaie de combiner 2 requêtes mysql en une requête en utilisant des sous-requêtes. J'ai actuellement les 2 requêtes séparemment qui produisent les résultats que je veux:Combinaison de 2 requêtes mysql en utilisant des sous-requêtes

Voici les 2 requêtes:

SELECT contact_id FROM contacts 
WHERE acc_id = 1 AND email LIKE "paul%" 

SELECT c0.contact_id 
FROM contact_tags c0 INNER JOIN contact_tags c1 
on c0.contact_id = c1.contact_id INNER JOIN contact_tags c2 
on c1.contact_id = c2.contact_id where c0.tag_id = 1 
AND c1.tag_id = 2 AND c2.tag_id = 3 

Voici quelques exemples de données des tables:

Contacts: 

contact_id acc_id  email 
    54   1  [email protected] 

Tags: 

id  contact_id  tag_id 
1   54   1 
2   54   2 
3   54   3 
4   50   1 
5   50   2 

Les deux requêtes lorsque exécuter indépendamment produire ce résultat qui est correct:

contact_id 
    54 

Cependant je suis tryi ng nicher une requête dans l'autre pour produire le même résultat à partir d'une seule requête:

Voici ce que j'ai essayé:

SELECT c0.contact_id 
FROM 
(
    SELECT contact_id 
    FROM contacts 
    WHERE acc_id = 1 AND email LIKE "paul%" 
) AS c0 
LEFT JOIN contact_tags AS c1 
ON c1.contact_id = c0.contact_id 
AND (
    SELECT c0.contact_id FROM contact_tags c0 
    INNER JOIN contact_tags c1 
    on c0.contact_id = c1.contact_id 
    INNER JOIN contact_tags c2 on c1.contact_id = c2.contact_id 
    where c0.tag_id = 1 AND c1.tag_id = 2 AND c2.tag_id = 3 
    ) 
WHERE c1.id IS NOT NULL 

Cependant je sais que ce ne va pas comme je veux revenir juste la seul identifiant de contact unique qui correspond à toutes les conditions ci-dessus:

contact_id 
    54 
    54 
    54 
    54 

Si quelqu'un pouvait me aider avec cela, il serait très apprécié.

Merci

+0

Pourquoi la première requête ne renvoie pas '50' aussi bien? –

+0

@ypercube - désolé c'est mon erreur la deuxième rangée ne devrait pas être là. Je vais l'enlever maintenant –

+0

Et vous voulez une requête qui montre que 'contact_id's sont dans les deux listes, non? –

Répondre

2
Select contact_id 
From contacts 
Where acc_id = 1 And email Like 'paul%' 
    And contact_id In (
          Select Tags1.contact_id 
          From contact_tags As Tags1 
          Where Tags1.tag_id In(1,2,3) 
          Group By Tags1.contact_id 
          Having Count(Distinct Tags1.tag_id) = 3 
          ) 

Ou:

Select contact_id 
From contacts 
Where contact_id In (
         Select C1.contact_id 
         From contact_tags As Tags1 
          Join contacts As C1 
           On C1.contact_id = Tags1.contact_id 
         Where Tags1.tag_id In(1,2,3) 
          And C1.acc_id = 1 
          And C1.email Like 'paul%' 
         Group By C1.contact_id 
         Having Count(Distinct Tags1.tag_id) = 3 
         ) 
+0

Quand je tente d'exécuter votre 2ème requête que je reçois l'erreur suivante: # 1054 - Unknown column 'C1.contact_id' in '/ ALL/ANY sous_requête' –

+0

Atkins @ Paul - C'est une faute de frappe. J'ai accidentellement inclus un alias dans la clause Where de la requête principale. Avoir réparé. – Thomas

+0

Merci cela semble fonctionner exactement comment j'en ai besoin. Bien que je ne peux pas comprendre ce que cette ligne fait 'Ayant Count (Distinct Tags1.tag_id) = 3'. Pouvez-vous recommander n'importe où que je peux lire sur ce que cette ligne atteint? Merci –

1

Pour avoir une requête qui renvoie tous les contacts qui seraient retournés à la fois la première et la seconde requête, utilisez ceci:

(en supposant que le premier ne retourne pas en double contact_id s)

SELECT contact_id 
FROM contacts 
WHERE acc_id = 1 
    AND email LIKE "paul%" 

    AND contact_id IN 

    (SELECT c0.contact_id 
    FROM contact_tags c0 
     INNER JOIN contact_tags c1 
     ON c0.contact_id = c1.contact_id 
     INNER JOIN contact_tags c2 
     ON c1.contact_id = c2.contact_id 
    WHERE c0.tag_id = 1 
     AND c1.tag_id = 2 
     AND c2.tag_id = 3 
)