2010-01-28 6 views
3

Avoir un utilisateur de table et il y a un champ invité_by_id montrant l'identifiant de la personne qui a invité cet utilisateur. Besoin de faire une requête MySQL retournant des lignes avec tous les champs des utilisateurs plus un champ invites_compte indiquant combien de personnes ont été invitées par chaque utilisateur. Quelque chose comme ceci:Comment créer une requête imbriquée?

SELECT 
    User.*, Count.count 
FROM 
    users AS User, 
    (
     SELECT COUNT(*) AS count FROM users WHERE users.invited_by_id=User.id 
    ) AS Count; 

Celui-ci ne fonctionne pas donc j'ai besoin un travail.

Répondre

5
SELECT u.*, 
     (
     SELECT COUNT(*) 
     FROM users ui 
     WHERE ui.invited_by_id = u.id 
     ) AS cnt 
FROM users u  
+0

+1: Oui, sous-requête dans la liste des colonnes. Cela fonctionne certainement aussi. Bonne réponse. – Asaph

+0

Cela gère également beaucoup plus facilement 'ORDER BY' et' LIMIT': n'évaluera pas la sous-requête tant qu'elle n'en aura pas vraiment besoin. – Quassnoi

+0

@Quassnoi: Mais va-t-il évaluer la sous-requête une fois pour chaque ligne? Si tel est le cas, cela peut entraîner des problèmes de performance dans les cas où vous n'utilisez pas 'ORDER BY' et' LIMIT'. – Asaph

4

Ok, tout d'abord, count est un mot réservé en sql donc vous ne pouvez pas l'utiliser comme un alias de table (à moins que vous le citez d'une certaine manière mais ne le faites pas). Deuxièmement, le vrai moyen de résoudre ce problème est d'introduire une clause GROUP BY dans votre sous-requête.

Essayez ceci:

SELECT user3.*, subquery.theCount FROM 
    users AS user3 
INNER JOIN ( 
    SELECT 
     user1.id, count(user2.id) AS theCount 
    FROM 
     users AS user1 
    LEFT OUTER JOIN 
     users AS user2 ON user2.invited_by_id=user1.id 
    GROUP BY user1.id 
) AS subquery ON subquery.id=user3.id; 

Voici un sale petit secret à propos de MySQL: Il vous permet de tricher avec la déclaration GROUP BY et sélectionner des colonnes qui ne sont pas dans la liste GROUP BY et pas non plus dans les fonctions d'agrégation. D'autres RMDMS ne vous permettent pas de faire cela.

SELECT 
    user1.*, count(user2.id) AS theCount 
FROM 
    users AS user1 
LEFT OUTER JOIN 
    users AS user2 ON user2.invited_by_id=user1.id 
GROUP BY user1.id; 
+1

+1, belle réponse –

+0

Merci. Ça me semble magique. Je ne comprends pas très bien les besoins et l'utilisation de GROUP BY. – vian

Questions connexes