74 votes

postgreSQL groupe par les différents à partir de mysql?

J'ai été à la migration de certains de mes requêtes mySQL à postgreSQL pour utiliser Heroku... la plupart de mes questions, beau travail, mais je continue à avoir un semblable récurrents d'erreur lorsque j'utilise du groupe par:

ERREUR: la colonne "XYZ" doit apparaître dans la clause GROUP BY ou être utilisé dans une fonction d'agrégation

Quelqu'un pourrait pourrait me dire ce que je fais mal?

MySQL qui fonctionne à 100%:

SELECT `availables`.* FROM `availables` INNER JOIN `rooms` ON `rooms`.id = `availables`.room_id WHERE (rooms.hotel_id = 5056 AND availables.bookdate BETWEEN '2009-11-22' AND '2009-11-24') GROUP BY availables.bookdate ORDER BY availables.updated_at

PostgreSQL erreur:

ActiveRecord::StatementInvalid: PGError: ERREUR: la colonne "disponibles.id" doit apparaître dans la clause GROUP BY ou être utilisé dans une fonction d'agrégation
: SÉLECTIONNEZ "disponibles".* DE "disponibles" INNER JOIN "chambres", "rooms".id = "disponibles".room_id OÙ (chambres.hotel_id = 5056 ET disponibles.bookdate ENTRE E'2009-10-21' ET E'2009-10-23') GROUP BY disponibles.bookdate COMMANDE PAR disponibles.updated_at

Code Ruby générer le SQL:

expiration = Available.find(:all,
    :joins => [ :room ],
    :conditions => [ "rooms.hotel_id = ? AND availables.bookdate BETWEEN ? AND ?", hostel_id, date.to_s, (date+days-1).to_s ],
    :group => 'availables.bookdate',
    :order => 'availables.updated_at')  

Sortie attendue (de travail de requête mySQL):

+-----+-------+-------+------------+---------+---------------+---------------+
| id | prix | spots | bookdate | room_id | created_at | updated_at |
+-----+-------+-------+------------+---------+---------------+---------------+
| 414 | 38.0 | 1 | 2009-11-22 | 1762 | 2009-11-20... | 2009-11-20... |
| 415 | 38.0 | 1 | 2009-11-23 | 1762 | 2009-11-20... | 2009-11-20... |
| 416 | 38.0 | 2 | 2009-11-24 | 1762 | 2009-11-20... | 2009-11-20... |
+-----+-------+-------+------------+---------+---------------+---------------+
3 rows in set

116voto

peufeu Points 4758

MySQL est totalement non conforme aux normes du GROUPE PAR peut être émulé par Postgres " DISTINCTS. Réfléchissez à ceci :

mysql :

SELECT a,b,c,d,e FROM table GROUP BY a

Cette offre 1 ligne par valeur d'un (dont l'un, vous ne savez pas vraiment). Eh bien en fait vous pouvez le deviner, parce que MySQL ne sais pas à propos de hachage agrégats, donc il va probablement utiliser une sorte... mais il ne sorte sur un, de sorte que l'ordre des lignes peut être aléatoire. Sauf si elle utilise un index multicolonne plutôt que de les trier. Eh bien, de toute façon, il n'est pas spécifié par la requête.

postgres :

SELECT DISTINCT ON (a) a,b,c,d,e FROM table ORDER BY a,b,c

Cette offre 1 ligne pour chaque valeur de a, cette ligne sera le premier à les trier en fonction de la COMMANDE PAR spécifié par la requête. Simple.

Notez qu'ici, ce n'est pas un agrégat je suis de l'informatique. De sorte que les groupes EN réalité n'a pas de sens. DISTINCTES SUR fait beaucoup plus de sens.

Rails est marié à MySQL, donc je ne suis pas surpris qu'il génère le SQL qui ne fonctionne pas dans postgres.

17voto

Erlock Points 1850

PostgreSQL est plus SQL conforme que MySQL. Tous les domaines à l'exception du champ calculé avec la fonction d'agrégation - dans la sortie doit être présent dans la clause GROUP BY.

11voto

Bozho Points 273663

MySQL GROUP BY peut être utilisé sans une fonction d'agrégation (ce qui est contraire à la norme SQL), et renvoie la première ligne dans le groupe (je ne sais pas en fonction de quels critères), tandis que PostgreSQL doit avoir une fonction d'agrégation (MAX, SUM, etc) sur la colonne, sur laquelle la clause GROUP BY est émis.

5voto

Omar Qureshi Points 5755

Correct, la solution pour corriger cela est à utiliser :sélectionnez et sélectionnez chaque champ que vous souhaitez décorer l'objet résultant avec de groupe et par eux.

Méchant - mais c'est la manière de groupe par devrait de travail, par opposition à la façon dont MySQL fonctionne avec elle en devinant ce que tu veux dire, si vous ne respectez pas les champs dans votre groupe.

3voto

Franz Points 5924

Si je me souviens bien, dans PostgreSQL, vous devez ajouter toutes les colonnes que vous les récupérer à partir de la table où le GROUPE PAR la clause s'applique à la clause GROUP BY.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X