2009-10-18 94 views
13

我有一个查询,它在同一个表中搜索两个单独的字段...查找最有可能是特定城市的位置,但也可能是一个国家...即需要两个领域。rails union hack,如何将两个不同的查询结合在一起

表的样子:

Country City 

Germany Aachen 
USA  Amarillo 
USA  Austin 

结果:

Keyword Sideinfo 

Aachen Germany 
USA  Country 
Austin USA 
Germany Country 

基本上我不知道是否有这样做,因为我必须使用两个单独的查询,然后将它们添加了更简洁的方式(它工作正常):

def self.ajax(search) 
    countries = Location.find(:all, :select=> 'country AS keyword, "Country" AS sideinfo', :joins => :hotels, :conditions => [ 'hotels.email IS NOT NULL AND country LIKE ?', "#{search}%" ], :group => :country) 
    cities = Location.find(:all, :select=> 'city AS keyword, country AS sideinfo', :joins => :hotels, :conditions => [ 'hotels.email IS NOT NULL AND city LIKE ?', "#{search}%" ], :group => :city) 
    out = cities + countries 
    out = out.sort { |a,b| a.keyword <=> b.keyword } 
    out.first(8) 
    end 

我找不到任何有关如何工会使用ActiveRecord ...

+1

此问题dis在ActiveRecord中使用或伪造联盟的方法:http://stackoverflow.com/questions/6686920/activerecord-query-union – 2014-08-05 02:17:20

回答

7

使用ActiveRecord执行UNION查询本身不是可能的。因此有两种解决方案:

  • 使用find_by_sql可以根据需要构建您的查询。我不会为此提供建议。
  • 使用像union这样的插件来执行UNION sql查询。
+4

现在联盟已经3岁了。任何人都有更新的解决方案 – 2012-04-19 22:24:37

+0

@BillLeeper虽然你的评论发布在'12,检查我的答案,以防万一你仍在寻找它 – 2015-06-26 07:45:05

+0

@BillLeeper https://github.com/brianhempel/active_record_union是一个更好的宝石。在没有丑陋的情况下使用ActiveRecord范围上的联合。 – lingceng 2015-10-09 02:35:09

2

使用UNION插件,它现在的作品精美的感谢:

def self.ajax3(search) 
    Location.union([{ :select => 'city AS keyword, country AS sideinfo', 
         :joins => :hotels, 
         :conditions => [ 'email IS NOT NULL AND city LIKE ?', "#{search}%" ]}, 
        { :select => 'country AS keyword, "Country" AS sideinfo', 
         :joins => :hotels, 
         :conditions => [ 'email IS NOT NULL AND country LIKE ?', "#{search}%" ]}]) 
    end 
3

我发现一个整洁的黑客使用选择。 例如,如果您想在User和OtherUser之间建立联合。

User.select('id from other_users union select id') 

这就会产生此SQL

"SELECT id from other_users union select id FROM users " 

如果有符合条件范围可以使用的ActiveRecord ::关系where_values方法

condition = OtherUser.example_condtion_scope.where_values.join(' ') 
User.select("id from other_users where #{contition}") 
1

这是现在可以在轨道4,5 ,

locations = Location.arel_table 
hotels = Hotel.arel_table 

countries = Location 
       .select(locations[:country].as("keyword")) 
       .joins(:hotels) 
       .where(hotels[:email].not_eq(nil)) 
       .where(locations[:country].matches("#{search}%")) 

cities = Location 
      .select(locations[:city].as("keyword")) 
      .joins(:hotels) 
      .where(hotels[:email].not_eq(nil)) 
      .where(locations[:city].matches("#{search}%")) 

union = countries.union(cities) 

result = Location.from(locations.create_table_alias(union, :locations).to_sql) 
相关问题