GroupingError:错误:列""必须出现在GROUP BY子句中或用于聚合函数

Ski*_*pex 4 ruby postgresql group-by ruby-on-rails heroku

我正在尝试创建一份留下评论的独特患者名单.代码字很好,直到我上传到heroku,它在postgresql中不起作用.

这是我创建列表的Ruby .erb代码:

<% @comments.group(:patient_id).each_with_index do |comment, index| %>
    <div class="profile-post color-one">
       <span class="profile-post-numb"><%= index+1 %></span>
        <div class="profile-post-in">
            <h3 class="heading-xs"><a><%= link_to "#{comment.patient.first_name} #{comment.patient.last_name}", comment_path(comment) %></a></h3>
            <p>Lastest comment from <%= time_ago_in_words(comment.created_at) %> ago<i class="pull-right"><%= link_to "Edit", edit_comment_path(comment) %> <%= link_to "Delete", comment_path(comment), method: :delete, data: {confirm: 'Are you sure you want to delete'} %></i></p>
        </div>
    </div>
<% end %>
Run Code Online (Sandbox Code Playgroud)

@comments在控制器中定义为:

def index
  @comments = current_clinician.comments.order("created_at desc")
end
Run Code Online (Sandbox Code Playgroud)

heroku日志给我这个错误信息:

PG::GroupingError: ERROR:  column "comments.id" must appear in the GROUP BY clause or be used in an aggregate function

LINE 1: SELECT "comments".* FROM "comments"  WHERE  comments"."clini...
               ^
SELECT "comments".* *FROM "comments"  WHERE "comments"."clinician_id" = $1 GROUP BY patient_id  ORDER BY created_at desc
Run Code Online (Sandbox Code Playgroud)

我尝试过其他SO问题的解决方案,例如20942477.其中说我应该将字段comments.id添加到我的组子句中:

<% @comments.group(:patient_id, :"comments.id").each_with_index do |comment, index| %>
Run Code Online (Sandbox Code Playgroud)

这消除了heroku上的错误,但是失败了组命令的目的 - 它不再仅显示独特的患者,而是列出所有患者.

我也尝试过1780893的解决方案 .哪个说我应该改变ORDER BY:

@comments = current_clinician.comments.order("substring(created_at,1.8) desc")
Run Code Online (Sandbox Code Playgroud)

这在本地给出了这个错误:

SQLite3 :: SQLException:没有这样的函数:substring:SELECT"comments".*FROM"comments"WHERE"comments"."clinician_id"=?ORDER BY substring(created_at,1.8)desc

我意识到这是一个常见的问题,我对SQL缺乏经验,因此我无法获取代码,因此它可以在我的开发和生产环境中工作.我在SO上读到的答案并没有使用Ruby来获取SQL并超过我的经验水平.

Erw*_*ter 8

不能合并SELECT *使用GROUP BY some_column的Postgres的(除非some_column是PK),因为这是一个矛盾.所有非聚合列(在聚合函数外的SELECT,HAVINGORDER BY子句中使用)必须位于GROUP BY列表中 - 其中主键列可以替换表的所有列.否则,未定义从聚合集中选择哪个值.

每个文件:

如果GROUP BY存在,或者存在任何聚合函数,则SELECT列表表达式无效以引用未聚合的列,但在聚合函数内或未分组列在功能上依赖于分组列时,因为否则可能存在多个要为未分组的列返回的值.如果分组列(或其子集)是包含未分组列的表的主键,则存在功能依赖性.

已知某个其他RDBMS在这里玩脏技巧并允许这个并选择任意值......

您似乎想要一份评论的独特患者列表,每个患者都有最新评论.Postgres中最简单的方法是DISTINCT ON:

SELECT DISTINCT ON (patient_id) *
FROM   comments
WHERE  clinician_id = $1
ORDER  BY patient_id, created_at DESC NULLS LAST;
Run Code Online (Sandbox Code Playgroud)

但这不会与SQLite一起飞行 - 它不应该在循环中开始:

NULLS LAST仅在created_at可以为NULL 时才相关:

详细信息DISTINCT ON: