2009-10-18 10 views
13

Ich habe eine Abfrage, die zwei separate Felder in der gleichen Tabelle sucht ... auf der Suche nach Orten, die höchstwahrscheinlich eine bestimmte Stadt sind, könnte aber auch ein Land sein ... dh die Notwendigkeit von zwei Feldern.Schienen Union Hack, wie man zwei verschiedene Abfragen zusammen

Tabelle wie folgt aussieht:

Country City 

Germany Aachen 
USA  Amarillo 
USA  Austin 

Ergebnis:

Keyword Sideinfo 

Aachen Germany 
USA  Country 
Austin USA 
Germany Country 

Im Grunde frage ich mich, ob es eine prägnante Art und Weise, dies zu tun, weil ich zwei separate Abfragen zu verwenden, hatte dann fügen Sie sortieren zusammen, sie usw. (was gut funktioniert):

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 

ich konnte keine Informationen finden, wie man Unionen, die ActiveRecord verwenden ...

+1

Diese Frage dis cuses Möglichkeiten, Gewerkschaften in ActiveRecord zu verwenden oder zu fälschen: http://stackoverflow.com/questions/6686920/activerecord-query-union –

Antwort

7

Das Ausführen einer UNION-Abfrage ist nicht nativ mit ActiveRecord möglich. Also gibt es zwei Lösungen:

  • Verwenden Sie find_by_sql, um Ihre Abfrage zu erstellen, wie Sie es wollen. Ich würde es nicht empfehlen.
  • Verwenden Sie ein Plugin wie union, um eine UNION SQL-Abfrage zu tun.
+4

Union ist jetzt 3 Jahre alt. Jeder bekam eine aktuellere Lösung –

+0

@BillLeeper obwohl Ihr Kommentar wurde in '12, überprüfen Sie meine Antwort, falls Sie noch danach suchen –

+0

@BillLeeper https://github.com/brianhempel/active_record_union ist ein besseres Juwel. Verwenden Sie Unionen auf ActiveRecord-Bereichen ohne Hässlichkeit. – lingceng

2

die Vereinigung Plugin verwenden, funktioniert es jetzt schön dank:

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

ich einen ordentlichen Hack mit ausgewählten gefunden. Zum Beispiel, wenn Sie eine Verbindung zwischen Benutzer und OtherUser herstellen möchten.

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

dies wird diese SQL

"SELECT id from other_users union select id FROM users " 

erzeugen Wenn Sie Bereiche mit den Bedingungen haben, können Sie die Activerecord :: Relation verwenden where_values ​​

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

Diese sind jetzt in Rails ist 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) 
Verwandte Themen