2010-06-28 14 views
11

Ich tue mein Bestes, um mein Gehirn um arel und die relationale Algebra dahinter zu beugen, aber wie man ein SELECT DISTINCT darstellt, entzieht sich ständig meinem Verständnis. Kann jemand erklären, wie man arel:Wie man unterschiedliche Werte mit arel/relationaler Algebra holt

SELECT DISTINCT title FROM posts; 

Vielen Dank!

+1

Ich weiß nicht, Arel aber aus meiner Lektüre von „Datenbank in Depth“ durch CJDate, das Ergebnis einer Abfrage in der relationalen Algebra ist eine Reihe von Tupel. Also, wenn Arel dieser Theorie folgt, dann sollte der Standard sein. –

Antwort

1

Post.select('DISTINCT title')

Update 1:

Zum Zeitpunkt der Post, war dies in Arel nicht zur Verfügung. In diesen Tagen, Active :: QueryMethods hat die uniq Methode (http://apidock.com/rails/ActiveRecord/QueryMethods/uniq), so würden Sie wollen:

Post.select(:title).uniq 

Update 2: Sieht aus wie Arel jetzt dieses Verhalten unterstützt. @maerics hat die richtige Antwort. Ich würde das löschen, wenn es nicht die akzeptierte Antwort war.

+0

Nicht gerade algebraisch, aber schwer mit der Effizienz zu argumentieren ;-) – jemmons

+2

Es gibt ein fatales Problem mit diesem Ansatz: Wenn Sie mehr als einen Bereich mit einer SELECT-Anweisung haben, kann das Verketten von SQL zu ungültigem SQL führen. –

+5

Dies ist nicht AREL, und daher beantwortet es die Frage nicht. –

6

Die vorherige Antwort ist der Weg Rails, nein? Nicht der Arel Weg.

Dies funktioniert für 1.x:

posts = Table(:posts) 
posts.project(Arel::Distinct.new(posts[:title])) 

Ich würde vermuten, es ist ein anderer „richtiger“ Weg, dies über die API zu tun, aber ich habe das noch nicht herausgefunden.

+4

Das scheint jetzt nicht zu funktionieren. –

+1

Das ist wahr. Diese Antwort war für Arel 1.x und wird nicht mehr funktionieren. – numbers1311407

+1

Weißt du, was ist die Alternative? –

3

Wenn Sie dies mit einem Umfang tun:

scope :recent, lambda {|count| 
    select("DISTINCT posts.*"). 
    joins(:whatever). 
    limit(count). 
    order("posts.updated_at DESC") 
    } 
0

Da AREL verwendet SET immer automatisch gelöscht werden, Betrieb, doppelte Zeile Ergebnisse ist. Verwenden Sie einfach eine normale Projekt (Phi) -Operation.

+0

Das ist eine schöne Idee in der Theorie, aber es ist offensichtlich falsch in der Realität. Arel-Abfragen geben doppelte Einträge aus jeder Projektion zurück, sofern sie nicht ausdrücklich durch die "distinct" -Methode eingeschränkt werden. – maerics

12

Verwendung von reinem Arel (nicht Rails/Active) eine "distinct" Methode ist:

Arel::VERSION # => '3.0.2' 
posts = Arel::Table.new(:posts) 
posts.project(posts[:title]) 
posts.distinct 
posts.to_sql # => 'SELECT DISTINCT "posts"."title" FROM "posts"' 

Merkwürdiger, das "distinct" Verfahren ist nicht verkettbar, je die anderen Arel Methoden.

+0

Ich suche schon seit einiger Zeit, vielen Dank! – Joe

+0

Mit Arel-Version, '5.0.1', funktioniert das nicht mehr :(. –

+1

Arel 6, alles funktioniert perfekt. Es ist auch verkettbar, da es SelectManager zurückgibt. – Slotos

8

Der Arel Weg, es zu tun ist:

t = Arel::Table.new(:foo) 
count_distinct = t[:field].count(true) 
count_distinct.to_sql # => "COUNT(DISTINCT `foo`.`field`)" 
+0

' count (true) 'funktioniert super für Arel 3 –

Verwandte Themen