【问题标题】:rails - how to subtract one query from another?rails - 如何从另一个查询中减去一个查询?
【发布时间】:2013-04-16 18:15:46
【问题描述】:

我想做这样的事情:

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

这样它就会执行 Room.find(3) 并仅返回该 SQL 记录,而不是 Room.find(1,2,3) 给我的 3 条记录

【问题讨论】:

  • 我刚试过,它可以工作......你最终会得到一个包含你的 ActiveRecord 对象的集合(这里是房间号 3)。减去两个包含所需 ID 的选项卡会更有效
  • 查看[this question][1]中给出的答案,我相信它可以进一步帮助您。 [1]:stackoverflow.com/questions/5842623/…
  • RAILS-4 和 RAILS-5 答案:stackoverflow.com/a/48934508/1536309

标签: sql ruby-on-rails ruby activerecord


【解决方案1】:

我认为这样会更有效率:

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

这样,您搜索您真正希望在查询中出现的 id,而不是获取不需要的行,然后实例化一堆 Room 对象,然后您会立即忽略这些对象,但 Ruby 仍然必须进行垃圾收集。

【讨论】:

    【解决方案2】:

    正如 Anthony Alberto 在评论中指出的那样。这行得通。只有当你只找到一个房间实例时这不起作用。例如Room.find(1) 将返回一个类Room 的对象,而不是一个数组。因此,您将无法在此 Speak 对象上使用二元运算符 -。为避免这种情况发生,请使用to_a 方法。

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

    【讨论】:

    • 这给了我:NoMethodError: undefined method 'to_a' for #<Room:0x959bba0>
    • 您使用的是哪个 Ruby 版本?
    • 不管怎样,你也可以试试这个。 Room.find(1,2,3) - [Room.find(1)]
    【解决方案3】:

    如果我省略了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 
    

    对比

    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 
    

    【讨论】:

    • 我很困惑你对什么有效和什么无效的概念。第一个做了 puts 应该做的事情,即打印 Room 对象和内存位置。无论如何,Link 类在这里做什么?
    【解决方案4】:

    您可以只使用 SQL 来执行此操作,这样就不会浪费内存!

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

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

    【讨论】:

      猜你喜欢
      • 2016-05-15
      • 1970-01-01
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多