13

我有一个查询,它在同一个表中搜索两个单独的字段...寻找最有可能是特定城市的位置,但也可能是一个国家...即需要两个字段。

表看起来像:

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 进行联合的信息...

4

4 回答 4

7

使用 ActiveRecord 本身无法执行 UNION 查询。所以有两种解决方案:

  • 使用find_by_sql根据需要构建查询。我不建议这样做。
  • 使用union之类的插件来执行 UNION sql 查询。
于 2009-10-18T11:12:42.113 回答
3

我使用 select 找到了一个巧妙的技巧。例如,如果您想在 User 和 OtherUser 之间建立联合。

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

这将生成此 SQL

"SELECT id from other_users union select id FROM users " 

如果您有条件范围,则可以使用 ActiveRecord::Relation where_values 方法

condition = OtherUser.example_condtion_scope.where_values.join(' ')
User.select("id from other_users where #{contition}")
于 2012-11-30T20:31:57.060 回答
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
于 2009-10-19T08:50:41.093 回答
1

这现在可以在 Rails 4 中实现,

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)
于 2015-06-26T07:44:20.643 回答