在Rails中选择Distinct的PostgreSQL错误

时间:2012-11-03 23:20:31

标签: ruby-on-rails ruby-on-rails-3 postgresql rails-postgresql

在Mysql上它可以正常工作。

  

PG ::错误:错误:对于SELECT DISTINCT,ORDER BY表达式必须   出现在选择列表LINE 1中:)ORDER BY   programs.rating DESC,program_sc ... ^:

查询:

  

SELECT DISTINCT“programs”。* FROM“programs”INNER JOIN   “program_schedules”ON“program_schedules”。“program_id”=   “program”。“id”WHERE(programs.rating> = 5 AND   program_schedules.start> ='2012-11-03 23:14:43.457659')AND(ptype =   '电影')ORDER BY programs.rating DESC,   program_schedules.start DESC

Rails代码:

  

@data =   Program.joins(:program_schedules).where('programs.rating> =?   AND program_schedules.start> =?',5,   Time.now).order('programs.rating DESC,   program_schedules.start DESC')。uniq

我试过

  

Program.select(“程序。*,   。program_schedules *)连接(:program_schedules)。凡(...

但是,这样,当我要读

  

@ data.program_schedules

我得到一个零值(当我知道没有零值时)

PostgreSQL 9.2(Heroku),Ruby 1.9.2

有关我的数据库的一些信息:

class Program < ActiveRecord::Base
   has_many :program_schedules
end


class ProgramSchedule < ActiveRecord::Base
  belongs_to :program
end

Schema.db

 create_table "program_schedules", :force => true do |t|
        t.integer  "program_id"
        t.datetime "start"
  end

  create_table "programs", :force => true do |t|
    t.string  "title",
    t.string  "ptype"
  end

修改 我不需要订购“programs_schedules”,因为我需要我的数组中与该程序相关的所有program_schedules。

1 个答案:

答案 0 :(得分:7)

您的查询有两种不明确的方式:

ptype不符合表格,您没有透露表格定义。所以查询不明确。

更重要的是,您想要:

ORDER BY programs.rating DESC, program_schedules.start DESC

但是,与此同时,您指示PostgreSQL从DISTINCT为您提供programs行。如果program_schedules中有多个匹配的行,那么Postgres如何知道要为ORDER BY子句选择哪一行?首先?持续?最早,最新,最环保?它只是未定义。

通常,ORDER BY子句不能与DISTINCT子句不一致,这就是错误消息告诉你的内容。

根据一些假设,填写缺少的信息,您的查询可能如下所示:

SELECT p.*
FROM   programs p
JOIN   program_schedules ps ON ps.program_id = p.id
WHERE  p.rating >= 5
AND    ps.start >= '2012-11-03 23:14:43.457659'
AND    p. ptype = 'movie'   -- assuming ptype is from programs  (?)
GROUP  BY p.id              -- assuming it's the primary key
ORDER  BY p.rating DESC, min(ps.start) DESC;  -- assuming smallest start

还假设你有PostgreSQL 9.0或更高版本,这是必须的。 (主键涵盖GROUP BY中的整个表。)

至于:

  

在Mysql上它可以正常工作。

不,不。它“有效”,但是以神秘的方式而不是“正确”。 MySQL允许出现各种奇怪的错误,并且不采取行动(以及SQL标准)以避免抛出异常 - 这是处理错误的一种非常不幸的方法。它会经常回来困扰你。 Demo on Youtube

问题更新

  

我需要我的数组中与该程序相关的所有program_schedules。

您可能想要添加:

SELECT p.*, array_agg(ps.start ORDER BY ps.start)