排序列必须出现在 GROUP BY 子句中

Sorting column must appear in the GROUP BY clause

我在 phoenix 应用程序中使用 数据库。我有一个 buses 的 table,每个都与一个或多个 stopsroutes 相关联。我正在尝试制作所有停靠点的可搜索列表,但我不想重写我的搜索和过滤功能(请参阅 list_filtered_buses)。

因此,在 sort_bus_list 中,我正在尝试 return 所有停靠点的排序列表。 我当前实现的问题是,当我在模板中呈现列表时,我得到了重复项,因为每辆公交车都return编辑了所有站点。我试过了两种不同的方法,一种是 return 重复,另一种是由于错误而阻止排序。

这里是buses.ex中sort_bus_list中的相关代码:

  # V1 - sortable, but returns duplicates
  list
    |> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
    |> group_by([b, s, r], [s.id, b.id])

  # V2 - doesn't return duplicates, but isn't returns error:
  # ERROR 42803 (grouping_error): column "b1.stop_id" must appear in the GROUP BY clause or be used in an aggregate function
    list
    |> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
    |> group_by([b, s, r], b.id)

这是我的模板的伪代码:

for bus in Buses
    for stop in bus
        display stop
    end
end 

更多 buses.ex 上下文代码:

 def list_filtered_buses(params) do
  search_term = params["filter"]["query"]

  from(t in Bus, join: a in assoc(t, :stops), join: c in assoc(t, :routes))
  |> search(search_term)
  |> list_buses_by_active(params)
  |> list_buses_by_type(params)
  |> sort_buses_list(params)
  |> preload([:stops, :routes])
 end


def sort_bus_list(list, params) do
  attrs = process_sorting_metrics(params)

  case params["filter"]["sort_attr"] do
    a when a == "stop_name" or a == "stop_id" ->

  #V2 - sortable, but returns duplcate
  list
    |> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
    |> group_by([b, s, r], [s.id, b.id])

  "route_name" ->
    list
    |> order_by([b, s, r], {^attrs.sort_dir, field(r, ^attrs.sort_attr)})
    |> group_by([b, s, r], [b.id, r.id])

  _ ->
    list
    |> order_by([b, s, r], {^attrs.sort_dir, field(b, ^attrs.sort_attr)})
    |> group_by([b, s, r], b.id)
  end
end

看起来,您正在尝试仅渲染 Stop。在 list_filtered_buses 函数中,您是 运行 对 Bus table 的查询。然后,您进一步尝试对数据进行排序和分组。 #V1 函数在 Bus.idStop.id 上进行分组,因此如果不同的 Bus 具有相同的 Stop,您会得到重复的 Stop。但是 #V2 函数 returns 错误,因为您正在 Bus 上执行 select 查询,而您仅在 Bus.id 上执行 group 并尝试从 Stop.

渲染属性

正如@AlekseiMatiushkin 所建议的那样,为了仅呈现不同的 Stops,您需要执行 from(s in Stop).