PostgreSQL ne me permet pas de grouper une colonne avec une commande
Dans PostgreSQL, je veux récupérer tous les utilisateurs à la fois et de les ordonner par date.
C'est ma requête:
SELECT id, useridx, isread, message, date
FROM messages
WHERE isread = 1
GROUP BY useridx
ORDER BY date DESC
C'est un des données de l'échantillon:
------------------------------------------------------
+ id | useridx | isread | messsage | date +
------------------------------------------------------
1 | 1 | 0 | Hello | 2012-01-01
2 | 2 | 1 | Hi | 2012-01-02
3 | 3 | 1 | Test | 2012-01-03
4 | 3 | 0 | My Msg | 2012-01-04
5 | 4 | 1 | sadasd | 2012-01-05
6 | 4 | 1 | sdfsdfd | 2012-01-06
7 | 4 | 0 | sdfsdfsd | 2012-01-07
8 | 5 | 0 | 5345634 | 2012-01-08
9 | 6 | 0 | sdfdfsd | 2012-01-09
10 | 7 | 0 | sdfsdfsf | 2012-01-10
------------------------------------------------------
Maintenant, ce que je veux faire est de récupérer cette table en les regroupant par useridx et de l'ordre par date.
Résultat Attendu:
------------------------------------------------------
+ id | useridx | isread | messsage | date +
------------------------------------------------------
6 | 4 | 1 | sdfsdfd | 2012-01-06
3 | 3 | 1 | Test | 2012-01-03
2 | 2 | 1 | Hi | 2012-01-02
------------------------------------------------------
Résultat Réel
ERROR: column "messages.date" must appear in the GROUP BY clause or be used in an aggregate function
Je ne veux pas de date de groupe. Je veux juste groupe avec useridx et de les trier par date DESC.
Toute aide/l'idée est apprécié!
Note: j'ai également essayé Distinctes. Ne pas l'adapter à mes besoins ou j'ai tort.
Je suis très confus et coincé entre DISTINCT ON
et rank()
méthodes.
Conclusion:
Pour qui se le même problème ici peut lire cela comme une réponse. @Kgrittn et @mu est trop court réponses sont correctes. Je vais continuer à utiliser à la fois des réponses et des schémas sur mon projet et dans le temps, je peux comprendre qui est le meilleur -je pense-. Alors, choisissez-en un et de poursuivre votre travail. Vous serez très bien.
Dernière mise à Jour: Parfois, Distinctes Sur exclut certains identifiants de résultat. Disons que j'ai une colonne id et j'ai 6 lignes qui est la même. Donc, distinctes sur exlude à partir du résultat, MAIS le classement (en) résultat juste. Ainsi, l'utilisation de rang()!
source d'informationauteur flower58
Vous devez vous connecter pour publier un commentaire.
Vous souhaitez utiliser le
rank()
de la fenêtre de la fonction d'ordonner les résultats au sein de chaqueuseridx
groupe, puis décoller le premier en enveloppant le classement des résultats dans une table dérivée:Qui donnera à votre les lignes avec
id
2, 3, et 6 à partir de votre échantillon. Vous pouvez ajouter une clé de tri secondaire dans leover
de toujours faire un choix lorsque vous avez plusieurs messages paruseridx
à la même date.Vous aurez besoin d'au moins PostgreSQL 8.4 (à ma connaissance) à avoir des fonctions de la fenêtre.
PostgreSQL, contrairement à MySQL, n'affiche pas de données aléatoires pour les colonnes qui ne sont pas regroupées dans une base de données de la requête.
Pour une explication plus longue et plus d'exemples : http://practiceovertheory.com/blog/2009/09/23/postgresql-s-group-by/
La solution est dans le message d'erreur
Ce qui signifie que vous devez regrouper PAR "messages.date de la colonne" ou l'utilisation d'une fonction d'agrégation comme MIN() et MAX() lors de la sélection de cette colonne
Exemple:
Une autre option est d'utiliser
SELECT DISTINCT ON
(ce qui est très différent d'un simpleSELECT DISTINCT
):Dans certains cas, cela peut l'échelle de mieux que les autres approches.
Vous de l'agrégation des résultats.
Cela signifie qu'au lieu de 2 lignes pour l'utilisateur
3
vous aurez juste une ligne. Mais vous pouvez également sélectionnerid
message
isread
colonnes pour l'ensemble de la ligne. Comment PostgreSQL est censé faire de ces données? Devrait-il êtremax()
de valeurs possibles? Peut-êtremin()
?Je suppose que vous voulez que les données sur les messages les plus récents. Essayez cette requête:
Ans plus tard, mais ne pouvez-vous pas simplement de l'ordre dans la sous-requête:
Cela fonctionne pour moi dans PostgreSQL 9.2