2010-06-28 11 views
11

Robię, co w mojej mocy, aby ugiąć mózg wokół arel i algebry relacyjnej za tym, ale jak reprezentować SELECT DISTINCT konsekwentnie umyka moje zrozumienie. Czy ktoś może wyjaśnić, jak arel:Jak uzyskać różne wartości za pomocą alfa/arel/relacyjnej

SELECT DISTINCT title FROM posts; 

Wielkie dzięki!

+1

nie wiem Arel ale z mojego czytania „Database In Depth” przez CJDate w relacyjnej algebry wynikiem zapytania jest zbiorem krotki. Jeśli więc isl podąża za tą teorią, to powinno być to ustawienie domyślne. –

Odpowiedz

1

Post.select('DISTINCT title')

Aktualizacja 1:

W czasie postu, to nie był dostępny w AREL. Te dni, ActiveRecord :: QueryMethods ma metodę uniq (http://apidock.com/rails/ActiveRecord/QueryMethods/uniq), więc czego chcesz:

Post.select(:title).uniq 

Aktualizacja 2: Wygląda Arel obsługuje teraz to zachowanie. @maerics ma poprawną odpowiedź. Usunąłbym to, gdyby nie zaakceptowana odpowiedź.

+0

Niezupełnie algebraiczny, ale trudny do sprzeciwienia się jego wydajnością ;-) – jemmons

+2

Występuje krytyczny problem z tym podejściem: jeśli masz więcej niż jeden zakres za pomocą instrukcji select, połączenie ich razem może spowodować niepoprawny SQL. –

+5

To nie jest AREL, a więc nie odpowiada na pytanie. –

6

Poprzednia odpowiedź to sposób Rails, nie? Nie sposób Arel.

Działa to dla 1.x:

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

Przypuszczam, że jest inny „bardziej poprawny” sposób to zrobić za pośrednictwem interfejsu API, ale nie zorientowali, że się jeszcze.

+4

To nie wydaje się teraz działać. –

+1

To prawda. Ta odpowiedź dotyczyła Arel 1.x i nie będzie już działać. – numbers1311407

+1

Czy wiesz, jaka jest alternatywa? –

3

Jeśli robisz to za pomocą zakresu:

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

Od AREL zawsze używa SET w Jest to operacja, zduplikowane wyniki wiersz zostanie usunięty automatycznie. Po prostu użyj normalnej operacji Project (Phi).

+0

To jest fajny pomysł w teorii, ale w rzeczywistości jest fałszywie fałszywy. Zapytania Arel zwrócą zduplikowane wpisy z dowolnej projekcji, chyba że zostaną wyraźnie ograniczone przez "odrębną" metodę. – maerics

12

użyciu czystego Arel (nie szyn/ActiveRecord) jest "różny" Metoda:

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"' 

ciekawe, "różny" metoda nie chainable, w inne metody arel.

+0

Szukałem tego przez jakiś czas, wielkie dzięki! – Joe

+0

Z wersją Arel, '5.0.1', to już nie działa :( –

+1

Arel 6, wszystko działa idealnie.Jest również przenośny, ponieważ zwraca SelectManager – Slotos

8

Arel sposób to zrobić to:

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

' count (true) 'działa świetnie dla Arel 3 –

Powiązane problemy