2009-10-05 7 views
2

Voici ma question:Problème avec DISTINCT!

SELECT 
DISTINCT `c`.`user_id`, 
`c`.`created_at`, 
`c`.`body`, 
(SELECT COUNT(*) FROM profiles_comments c2 WHERE c2.user_id = c.user_id AND c2.profile_id = 1) AS `comments_count`, 
`u`.`username`, 
`u`.`avatar_path` 
FROM `profiles_comments` AS `c` INNER JOIN `users` AS `u` ON u.id = c.user_id 
WHERE (c.profile_id = 1) ORDER BY `u`.`id` DESC; 

Il fonctionne. Le problème est cependant avec le mot DISTINCT. Si je comprends bien, il ne devrait sélectionner qu'une seule ligne par c.user_id. Mais ce que j'obtiens est même 4-5 lignes avec la même colonne c.user_id. Où est le problème?

Répondre

9

fait, DISTINCT ne se limite pas à la colonne 1, essentiellement lorsque vous dites:

SELECT DISTINCT a, b

Ce que vous dites est, « donnez-moi la valeur distincte a et b combiné ".. tout comme un index UNIQUE multi-colonnes

6

distinct fera en sorte que toutes les valeurs dans votre clause select sont uniques, pas seulement user_id. Si vous souhaitez limiter les résultats à user_ids, vous devez grouper par user_id.

Peut-être ce que vous voulez est:

SELECT 
`c`.`user_id`, 
`u`.`username`, 
`u`.`avatar_path`, 
(SELECT COUNT(*) FROM profiles_comments c2 WHERE c2.user_id = c.user_id AND c2.profile_id = 1) AS `comments_count` 
FROM `profiles_comments` AS `c` INNER JOIN `users` AS `u` ON u.id = c.user_id 
WHERE (c.profile_id = 1) 
GROUP BY `c`.`user_id`, 
`u`.`username`, 
`u`.`avatar_path` 
ORDER BY `u`.`id` DESC; 
2

œuvres DISTINCTS au niveau de la ligne, non seulement un niveau de la colonne

Si vous voulez que le Distinct d'une seule colonne, vous devrez regrouper le reste des colonnes retournées (MIN, MAX, SUM, AVG, etc.)

SELECT DISTINCT (Name), Min (ID) 
From MyTable 
+0

Et vous aurez besoin de déterminer laquelle des lignes multiples que vous voulez retourner. Fait une grande différence si vous sélectionnez max ou min ou quoi que ce soit. Aussi, si vous voulez que le dqata de chaque colonne provienne du même enregistrement, il peut être encore plus complexe que d'utiliser une fonction min(). – HLGEM

+0

@HLGEM a absolument raison.DISTINCT avec des fonctions agrégées peut être fait, mais à moins que vous compreniez les implications, ce n'est clairement pas une bonne idée. –

1

mal compris. Le modificateur DISTINCT s'applique à toute la ligne - il indique qu'aucune ROWS identique ne sera retournée dans le jeu de résultats.

En regardant votre SQL, quelle valeur de plusieurs disponibles attendez vous dans la colonne created_at (par exemple)? Il serait impossible de prédire les résultats de la requête comme écrit.

De plus, vous utilisez deux fois le profil_comments dans votre SELECT. Il semble que vous essayez d'obtenir un compte du nombre de fois que chaque utilisateur a commenté. Si oui, ce que vous voulez faire est d'utiliser une requête AGGREGATE, groupée sur user_id et n'incluant que les colonnes qui identifient de façon unique un utilisateur avec un nombre de commentaires:

SELECT user_id, COUNT (*) FROM profile_comments O WH profile_id = 1 GROUP BY id_utilisateur

Vous pouvez ajouter la jointure aux utilisateurs pour obtenir le nom d'utilisateur si vous le souhaitez mais, logiquement, votre jeu de résultats ne peut pas inclure d'autres colonnes de profile_comments et produire toujours une seule ligne par user_id sauf si ces colonnes sont également agrégé d'une certaine manière:

SELECT ID_utilisateur, MIN (created_at) AS Au plus tôt, MAX (created_at) AS Dernier, COUNT (*) FROM profile_comments WHERE nom_profil = 1 GROUPE BY user_id