【问题标题】:Count by association: syntax error at or near "AS"按关联计数:“AS”处或附近的语法错误
【发布时间】:2015-09-19 04:18:35
【问题描述】:

我正在尝试根据某个演员上过多少次来订购一组电视节目。我关注了其他一些堆栈溢出问题,提出了同样的问题,但我遇到了一个我在任何地方都没有提到的错误。

 Show.joins(:contributions)
  .select('show.*, COUNT(contributions.id) AS guest_count')
  .where('contributions.role_id = 2')
  .where('contributions.person_id IN (?)', self.id)
  .order('guest_count desc')

PG::SyntaxError: 错误: "AS" LINE 1: SELECT 处或附近的语法错误 COUNT(show.*, COUNT(contributions.id) AS guest_co...

输出:

: SELECT COUNT(COUNT(contributions.id) AS guest_count, show.*) FROM
"show" INNER JOIN "episodes" ON "episodes"."show" = "show"."id" 
INNER JOIN "contributions" ON "contributions"."episode_id" = 
"episodes"."id" WHERE (contributions.role_id = 2) AND 
(contributions.person_id IN (42))

这是我一直关注的堆栈溢出:Rails 3 ActiveRecord: Order by count on association

【问题讨论】:

  • 能贴出sql解释的结果吗?
  • 好主意,谢谢提醒!
  • 你不会得到 explain 的结果,因为这是一个语法错误。

标签: ruby-on-rails postgresql activerecord


【解决方案1】:

看起来 arel 没有正确设置您的 SQL 语句。尝试反转选择中的条件。

.select('COUNT(contributions.id) AS guest_count, show.*')

也许这会帮助他们。

编辑:

您还有第二个问题。您正在尝试使用聚合函数,但未指示您要分组的列。使用聚合时不要使用show.*,而是列出要选择的列。之后,使用group 方法列出列,以便它们可以包含在聚合查询中。

编辑 2:

你可以使用类似的东西吗:

shows = Show.includes(:contributions).all

并通过以下方式访问计数:

shows.first.contributions.count

或者这是您正在优化的性能问题?

【讨论】:

  • 对于像“权力的游戏”这样的节目,我想要一个按顺序列出最常见角色的表格(他们上演的次数,在这种情况下是“贡献”)。跨度>
  • 您关于颠倒订单的提示(首先放置 COUNT())解决了我从 rails 3.2 升级后的问题
【解决方案2】:

原始 SQL 可能如下所示:

SELECT s.*, x.ct
FROM   shows s
LEFT JOIN (
   SELECT e.show, count(*) AS ct
   FROM   episodes e
   JOIN   contributions c ON e.id = c.episode_id
   WHERE  c.role_id = 2
   AND    c.person_id = ?  -- self.id
   GROUP  BY 1
   ) x ON s.id = x.show
ORDER  BY x.ct DESC NULLS LAST;

这包括没有任何人出现的节目,但要注意将这些节目排在最后。要排除这些节目,请使用 JOIN 而不是 LEFT JOIN

考虑:

【讨论】:

    【解决方案3】:

    您必须将show 表更改为shows

    Show.joins(:contributions)
      .select('shows.*, COUNT(contributions.id) AS guest_count')
      .where('contributions.role_id = 2')
      .where('contributions.person_id IN (?)', self.id)
      .group("shows.id")
      .order('guest_count desc')
    

    【讨论】:

    • 同样的错误:PG::SyntaxError:错误:“AS”第 1 行或附近的语法错误:SELECT COUNT(show.*, COUNT(contributions.id) AS guest_co... ^ : SELECT COUNT(show.*, COUNT(contributions.id) AS guest_count) FROM "show" INNER JOIN "episodes" ON "episodes"."show_id" = "show"."id" INNER JOIN "contributions" ON "contributions"。 "episode_id" = "episodes"."id" WHERE (contributions.role_id = 2) AND (contributions.person_id IN (42)) :(
    • 根据您的错误,您没有在选择查询中将 show 更改为 shows。再试一遍。 :)
    • 我以为我做到了。我只是在重新启动后再次尝试,我得到了一个不同的错误:) PG::GroupingError: ERROR: column "shows.id" 必须出现在 GROUP BY 子句中或用于聚合函数第 1 行:SELECT 显示。* , COUNT(contributions.id) AS guest_count FR... ^ : SELECT shows.*, COUNT(contributions.id) AS guest_count FROM "shows" INNER JOIN "episodes" ON "episodes"."show_id" = "shows"。 "id" INNER JOIN "contributions" ON "contributions"."episode_id" = "episodes"."id" WHERE (contributions.role_id = 2) AND (contributions.person_id IN (42)) ORDER BY guest_count desc
    • 没关系。我想,Postgres 需要group_by 来计算你的guest_count。我稍后会更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-05
    • 1970-01-01
    • 2018-01-26
    • 2014-04-26
    • 1970-01-01
    • 2017-02-20
    • 2013-09-10
    相关资源
    最近更新 更多