PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

PostgreSQL -doit apparaître dans la clause GROUP BY ou être utilisé dans une fonction d'agrégation

Si user_id est la CLÉ PRIMAIRE alors vous devez mettre à niveau PostgreSQL ; les versions plus récentes géreront correctement le regroupement par clé primaire.

Si user_id n'est ni unique ni la clé primaire pour la relation 'states' en question, alors cette requête n'a pas beaucoup de sens, puisque PostgreSQL n'a aucun moyen de savoir quel valeur à renvoyer pour chaque colonne de estates où plusieurs lignes partagent le même user_id . Vous devez utiliser une fonction d'agrégation qui exprime ce que vous voulez, comme min , max , avg , string_agg , array_agg , etc ou ajoutez la ou les colonnes d'intérêt au GROUP BY .

Vous pouvez également reformuler la requête pour utiliser DISTINCT ON et un ORDER BY si vous voulez vraiment choisir une ligne quelque peu arbitraire, bien que je doute vraiment qu'il soit possible de l'exprimer via ActiveRecord.

Certaines bases de données - y compris SQLite et MySQL - choisiront simplement une ligne arbitraire. Ceci est considéré comme incorrect et dangereux par l'équipe PostgreSQL, donc PostgreSQL suit la norme SQL et considère ces requêtes comme des erreurs.

Si vous avez :

col1    col2
fred    42
bob     9
fred    44
fred    99

et vous faites :

SELECT col1, col2 FROM mytable GROUP BY col1;

alors il est évident que vous devriez obtenir la ligne :

bob     9

mais qu'en est-il du résultat pour fred ? Il n'y a pas de réponse correcte unique à choisir, donc la base de données refusera d'exécuter de telles requêtes non sécurisées. Si vous vouliez le plus grand col2 pour tout col1 vous utiliseriez le max agrégé :

SELECT col1, max(col2) AS max_col2 FROM mytable GROUP BY col1;