2009-10-18 8 views
13

Tengo una consulta que busca dos campos separados en la misma tabla ... buscando ubicaciones que probablemente sean una ciudad específica, pero también podría ser un país ... es decir, la necesidad de dos campos.carriles union hack, cómo juntar dos consultas diferentes

tabla siguiente aspecto:

Country City 

Germany Aachen 
USA  Amarillo 
USA  Austin 

Resultado:

Keyword Sideinfo 

Aachen Germany 
USA  Country 
Austin USA 
Germany Country 

Básicamente estoy preguntando si hay una manera más concisa para hacer esto porque tenía que usar dos consultas individuales y luego añadirlos juntos, ordenarlos, etc. (que funciona bien):

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 

No he podido encontrar ninguna información sobre cómo Uniones que utilizan ActiveRecord ...

+1

Esta pregunta dis Cuestiona formas de usar o falsificar sindicatos en ActiveRecord: http://stackoverflow.com/questions/6686920/activerecord-query-union –

Respuesta

7

Hacer una consulta UNION no es posible de forma nativa con ActiveRecord. Entonces hay dos soluciones:

  • Usando find_by_sql para generar su consulta como desee. Yo no lo aconsejaría.
  • Usando un complemento como union para hacer una consulta UNION sql.
+4

Union tiene 3 años. Alguien tiene una solución más actualizada –

+0

@BillLeeper aunque su comentario fue publicado en '12, verifique mi respuesta en caso de que todavía lo esté buscando –

+0

@BillLeeper https://github.com/brianhempel/active_record_union es una joya mejor. Use uniones en los ámbitos ActiveRecord sin fealdad. – lingceng

2

Utilizando el plugin de unión, que ahora funciona muy bien gracias:

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

me encontré con un corte claro utilizando selecto. Por ejemplo, si desea establecer una unión entre Usuario y Otro usuario.

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

esto generará este SQL

"SELECT id from other_users union select id FROM users " 

Si tiene alcances con las condiciones que usted puede utilizar el ActiveRecord :: Relation where_values ​​método

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

Esto es ahora posible en los carriles 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)