2009-10-01 6 views
1

J'ai une requête comme ceci:Comment faire fonctionner LEFT JOIN avec grouping/count dans MySQL?

SELECT type.id, type.name, COUNT(*) AS tot 
FROM page 
LEFT JOIN type ON page.type=type.id 
GROUP BY type.id 

Toutefois, cela ne sélectionne pas tous les types: il manque à tous les types qui ne sont pas dans le Tableau de la page. Je veux juste qu'il liste chaque type avec un nombre représentant combien de pages ont ce type, y compris 0 où le type ne se produit pas. Ai-je besoin d'une jointure différente?

Répondre

3

Faites un RIGHT JOIN à la place. Essayez ceci:

SELECT type.id, type.name, COUNT(page.type) AS tot 
FROM page 
RIGHT JOIN type ON page.type=type.id 
GROUP BY type.id 

Notez la manière différente de compter. page.type sera NULL pour les types qui n'ont pas pages. Ces lignes seront ignorées lors de l'exécution de COUNT

[EDIT] Voici un exemple. Si nous avons les données suivantes:

 
    type 
id name 
1  A 
2  B 
3  C 

    page 
id type 
1  1 
2  1 
3  2 

Si nous faisons le JOIN comme dans ma réponse (pas GROUP BY ou COUNT), notre jeu de résultats ressemblera à ceci:

 
type.id type.name page.id page.type 
     1   A  1   1 
     1   A  2   1 
     2   B  3   2 
     3   C  NULL  NULL 

Maintenant, quand nous faisons GROUP BY et COUNT(type.id), nous comptons les lignes où type.id n'est pas NULL. Ce serait toutes les lignes: résultat est 2 A et 1 pour B et C.

Si nous faisons à la place COUNT(page.type), nous obtenons 2 A, 1 B et 0 C (parce page.type était NULL C !)

+0

J'ai essayé ceci en utilisant count (*) avant de lire correctement votre réponse, et le type manquant a renvoyé 2 comme nombre. Utiliser count (page.type) comme vous l'avez dit donne 0. Pourquoi cela arrive-t-il? – DisgruntledGoat

+0

Il semble que l'utilisation de count (type.id) renvoie 2 également. – DisgruntledGoat

+1

'COUNT (*)' compte toutes les lignes. 'COUNT (page.type)' ne compte que les lignes où page.type n'est pas NULL. Lorsque vous faites un JOIN comme dans ma réponse, les lignes pour 'types' qui n'ont pas de' pages' ont toutes les colonnes 'page' définies à NULL. Quand nous faisons 'COUNT (page.type)', nous ne comptons que les lignes de 'types' qui ont' pages' (les colonnes de la page ne sont pas nulles). – hrnt

0

UTILISATION Coalesce pour donner une valeur à GROUP BY

SELECT 
    COALESCE(type.id, 0), 
    COALESCE(type.name, 'NoType'), 
    COUNT(*) AS tot 
FROM 
    page 
LEFT JOIN 
    type 
ON 
    page.type=type.id 
GROUP BY 
    COALESCE(type.id, 0), 
    COALESCE(type.name, 'NoType') 
2
NULL

une jointure gauche ramène toutes les lignes de la table sur le côté gauche de la jointure expression peu importe si elles existent sur la table à droite côté essayez ceci (les côtés de commutation de l'expression):

SELECT type.id, type.name, COUNT(*) AS tot 
FROM type 
LEFT JOIN page ON type.id=page.type 
GROUP BY type.id, type.name