2012-10-16 5 views
2

Voici ce que j'essaie de faire. J'ai une table avec des évaluations d'utilisateurs qui peuvent contenir des lignes en double. Je cherche à obtenir seulement DISTINCT valeurs pour chaque utilisateur.MySQL SELECT Multiple DISTINCT COUNT

Dans l'exemple du tableau ci-dessous. Si seuls les ID utilisateur 1 et 50 appartiennent à l'emplacement spécifique, seuls les ID vidéo uniques pour chaque utilisateur doivent être renvoyés sous la forme COUNT. L'utilisateur 1 a passé la vidéo 1, 2 et 1. Cela ne devrait donc être que 2 enregistrements, et l'utilisateur 50 a passé la vidéo 2. Donc le total pour cet emplacement serait 3. Je pense que j'ai besoin de deux DISTINCT's dans la requête, mais je suis Je ne sais pas comment faire cela.

+-----+----------+----------+ 
| id | video_id | user_id | 
+-----+----------+----------+ 
| 1 |  1 |  1 | 
| 2 |  2 |  50 | 
| 3 |  1 |  115 | 
| 4 |  2 |  25 | 
| 5 |  2 |  1 | 
| 6 |  6 |  98 | 
| 7 |  1 |  1 | 
+-----+----------+----------+ 

Voici à quoi ressemble ma requête actuelle.

$stmt2 = $dbConn->prepare("SELECT COUNT(DISTINCT user_assessment.id) 
FROM user_assessment 
LEFT JOIN user ON user_assessment.user_id = user.id 
WHERE user.location = '$location'"); 
$stmt2->execute(); 
$stmt2->bind_result($video_count); 
$stmt2->fetch(); 
$stmt2->close(); 

Donc, ma requête renvoie tous le compte pour cet endroit précis, mais il ne manque pas les résultats non-uniques de chaque utilisateur spécifique.

Espérons que cela a du sens, merci pour l'aide.

+0

Pas de solution mais une optimisation: utilisez INNER JOIN. Il est plus rapide que LEFT JOIN, et l'effet est le même, puisque vous utilisez la table jointe dans la clause WHERE. – GolezTrol

+0

Et saviez-vous que les sauts de ligne sont autorisés dans les requêtes SQL? – GolezTrol

+0

@GolezTrol, oui merci. C'est juste comment j'ai copié le code que j'ai perdu les sauts de ligne. J'ai édité mon post pour le rendre un peu plus facile à lire. – Jako

Répondre

1

La requête ci-dessous joint une sous-requête qui extrait les vidéos distinctes par utilisateur. Ensuite, la requête principale fait une somme sur ces nombres pour obtenir le total des vidéos pour l'emplacement.

SELECT 
    SUM(video_count) 
FROM 
    user u 
    INNER JOIN 
    (SELECT 
     ua.user_id, 
     COUNT(DISTINCT video_id) as video_count 
    FROM 
     user_assessment ua 
    GROUP BY 
     ua.user_id) uav on uav.user_id = u.user_id 
WHERE 
    u.location = '$location' 

Notez que puisque vous utilisez déjà des liaisons, vous pouvez également passer $location dans un paramètre de liaison. Je vous laisse cela, car cela ne fait pas partie de la question. ;-)

+0

Vous êtes un génie, ça a parfaitement fonctionné. Merci beaucoup pour l'aide! – Jako

6
SELECT COUNT(DISTINCT ua.video_id, ua.user_id) 
FROM user_assessment ua 
INNER JOIN user ON ua.user_id = user.id 
WHERE user.location = '$location' 

Vous pouvez écrire beaucoup de choses à l'intérieur d'un COUNT donc ne pas hésiter à mettre ce que vous voulez exactement en elle. Cela donnera le nombre de différents couples (video_id, user_id), ce qui est ce que vous vouliez si j'ai bien compris.

+0

Merci pour votre aide, cette requête a également bien fonctionné pour moi. – Jako

+2

+1 Je n'étais pas sûr et je n'avais pas de base de données à tester, mais si cela fonctionne, c'est mieux que ma réponse. Plus compact, plus clair et probablement plus rapide. – GolezTrol