2013-02-19 7 views
0

Fondamentalement, j'ai deux tablesenregistrements Sélectionnez sans aucun des documents connexes de certains types

articleID 
    1 
    2 
    3 
    4 


relatedType | articleID 
    3    1 
    4    1 
    3    2 
    4    3 
    5    3 
    2    4 

je dois sélectionner le articleID qui n'a pas de documents connexes avec type > 3. Avec cet ensemble de données, je dois essentiellement:

articleID 
2 
4 

Parce que leur type connexe ne contiennent que 3 et 2.

je con avec cette requête:

SELECT * FROM article 
    WHERE articleID NOT IN (SELECT articleID FROM relatedTable 
        ^  WHERE type > 3 GROUP BY portalid) 
        | 
        |--- NOT IN does the trick! 

mais je voudrais éviter imbriquée requête car cette requête est assez lente. Un indice?

Répondre

1

Vous pouvez faire

SELECT * FROM article a 
WHERE NOT EXISTS 
(SELECT NULL FROM relatedTable b WHERE b.type > 3 
    AND b.articleID = a.articleID)  

Techniquement, les 3 façons d'atteindre les résultats souhaités (NOT IN, NOT EXISTS, LEFT JOIN) doivent se comporter (pour la colonne non annulable) et générer normalement le même plan d'exécution, sauf mysql où NOT IN n'est pas recommandé (ou n'était pas recommandé avant 5.5, peut-être qu'il a changé).
Je voudrais aussi blâme GROUP BY dans votre requête d'origine pour de mauvaises performances et ...

+0

Je crois que EXISTS est encore plus lent que PAS DANS – dynamic

+0

Mais! Tu avais raison, le problème était GROUP BY. Il a ajouté 10sec à la dernière fois (maintenant c'est sous 0.5 sec) – dynamic

+0

@llnk: vous pouvez avoir raison à propos de mysql, je n'ai pas travaillé avec lui pendant un certain temps ... Cependant; Je crois que cela peut (et devrait) changer à l'avenir. – a1ex07

1

Utilisation OUTER JOIN

SELECT a.articleID 
FROM article a LEFT OUTER JOIN relatedTable r 
ON (a.articleID = r.articleID and r.relatedType > 3) 
WHERE r.articleID IS NULL 

CORRECTION: Désolé, je viens de réaliser que la demande était de ne pas avoir les lignes qui a énuméré tous les enregistrements de type> 3. Vous pouvez faire encore en ayant un sous -query dans le JOIN ou en créant une table temporaire, en l'indexant puis en la rejoignant. Le fait que l'une d'entre elles soit réellement plus rapide que la sous-requête NOT IN dépendra de la version de MySQL et, plus important encore, de la taille et des statistiques de la table.

+0

Intéressant ... une condition à l'intérieur de ON (...)? – dynamic

+0

Yeap. En fait, c'est la deuxième fois aujourd'hui quand je fais la promotion de la condition dans le ON() voir [http://stackoverflow.com/questions/14968414/mysql-truly-distinct-join/14968594#14968594] –

+0

@llnk Ce n'est pas résoudre le problème. –

0

Si vous avez besoin seulement id article, essayez ceci:

SELECT 
    articleID 
FROM relatedTable 
GROUP BY articleID 
HAVING MAX(relatedType) <= 3 

ou vous pouvez vous joindre à votre table ce article .

Questions connexes