Rails 3使用select distinct

时间:2013-02-22 20:18:37

标签: sql ruby-on-rails ruby-on-rails-3 select distinct

我需要加入3个桌子。

我有EventsPlacesBoroughs

地方属于自治市并且有很多活动

从某一天的事件清单中,我想查找所有不同行政区的清单。

Event.where(day_of_week: 2).joins(:place,:borough).select("DISTINCT(boroughs.name) AS name")

生成SQL:

SELECT DISTINCT(boroughs.name) AS name FROM "events" INNER JOIN "places" ON "places"."id" =        
"events"."place_id" INNER JOIN "places" "places_events_join" ON "places_events_join"."id" = 
"events"."place_id" INNER JOIN "boroughs" ON "boroughs"."id" = 
"places_events_join"."borough_id" WHERE "events"."active" = 't' AND "events"."day_of_week" = 3

当我把它扔进我的postgres数据库控制台时,它看起来很完美,但是对于我的rails控制台我得到了。

#<Event >, #<Event >, #<Event >, #<Event >, #<Event >, #<Event >, #<Event >, #<Event >, #<Event >, #<Event >

更新:

Mr. Walrus的建议完美无缺,但我仍然感到困惑的是,当SQL本身产生相同的结果时,为什么反过来不起作用。

Borough.joins(:events).where(:events => {:day_of_week => 2}).select("DISTINCT(boroughs.name) AS name")

制作:

[#<Borough name: "richmond">, #<Borough name: "southwark">, #<Borough name: "brent">, #<Borough name: "city of london">] 

但是这个

Event.where(:events => {:day_of_week => 2}).joins(:borough).select("DISTINCT(boroughs.name) AS name")

产地:

[#<Event >, #<Event >, #<Event >, #<Event >, #<Event >] 

4 个答案:

答案 0 :(得分:3)

您需要为列命名,否则ActiveRecord将不知道如何映射它。

Event.where(day_of_week: 2).joins(:place,:borough).select('DISTINCT(boroughs.name) as "bouroughs.name"')

答案 1 :(得分:2)

我想我会这样做:

Borough.joins(:events).where(:events => {:day_of_week => 2})

Rails默认使用内连接,因此它会排除任何没有匹配事件的自治市镇。实际上,您根本不需要为查询放置数据。

答案 2 :(得分:2)

从Rails 3.2开始,尝试Pluck

Event.where(:events => {:day_of_week => 2}).joins(:borough).uniq.pluck('boroughs.name')

应该工作。

如果您计划在预先警告范围的情况下对其进行链接,则延迟加载会导致其无法按预期工作,而是执行类似

的操作
def self.somemethod
  joins(:borough).pluck('boroughs.name').uniq
end

答案 3 :(得分:1)

首先,为列名称添加别名

select("DISTINCT boroughs.name as borough_name")

然后将该名称作为字段访问。

events = Event.where(day_of_week: 2).joins(:place,:borough).select("DISTINCT boroughs.name as borough_name")
events.map{|event| event.borough_name}