rails - 如何从另一个查询中减去一个查询?

时间:2013-04-16 18:15:46

标签: sql ruby-on-rails ruby activerecord

我想做这样的事情:

puts Room.find(1,2,3) - Room.find(1,2)

这样它Room.find(3)只返回那条SQL记录,而不是Room.find(1,2,3)给我的3条记录

4 个答案:

答案 0 :(得分:6)

我认为这会更有效率:

first_id_list = [1, 2, 3]
second_id_list = [1, 2]
Room.find(first_id_list - second_id_list)

这样,你搜索你真正想要在你的查询中的id,而不是获取不需要的行,然后实例化一堆Room对象,然后你迅速忽略但Ruby仍然必须垃圾收集。

答案 1 :(得分:2)

安东尼·阿尔贝托在评论中指出。这有效。只有当你找到一个房间实例时,这种情况才会起作用。例如,Room.find(1)将返回类Room的对象,而不是数组。因此,您将无法在此Speak对象上使用二元运算符-。要避免这种情况发生,请使用to_a方法。

Array.wrap(Room.find(1,2,3)) - Array.wrap(Room.find(1))
=> Room.find(2,3)

答案 2 :(得分:1)

如果我遗漏puts ...

,它会有效
1.9.3-p327 :029 > puts Link.find(1,2,3) - Room.find(1,2)
Room Load (0.5ms)  SELECT `links`.* FROM `rooms` WHERE `rooms`.`id` IN (1, 2, 3)
Link Load (0.4ms)  SELECT `links`.* FROM `rooms` WHERE `rooms` id` IN (1, 2)
#<Room:0x95bf6a4>
 => nil 

VS

1.9.3-p327 :026 > Link.find(1,2,3) - Link.find(1,2)
  Room Load (0.8ms)  SELECT `rooms`.* FROM `rooms` WHERE `rooms`.`id` IN (1, 2, 3)
  Room Load (0.4ms)  SELECT `rooms`.* FROM `rooms` WHERE `rooms`.`id` IN (1, 2)
 => [#<Room id: 3, url_address: "http://www.linux.org", alt_text: "Linux", group_id: 3, position: 347, created_at: "2010-10-26 14:41:05", updated_at: "2010-10-26 14:41:05", version_number: "", content_date: nil>] 
1.9.3-p327 :027 > puts Room.find(1,2)
  Room Load (0.3ms)  SELECT `rooms`.* FROM `rooms` WHERE `rooms`.`id` IN (1, 2)
#<Room:0x9724094>
#<Room:0x9723ea0>
 => nil 

答案 3 :(得分:0)

你可以只使用SQL来做到这一点,这样你就不会浪费内存!

rooms = Room.where(id: [1,2,3])
            .where.not(id: [1,2])

OR

rooms = Room.where("id IN (?) AND id NOT IN (?)",[1,2,3], [1,2])