2010-06-28 24 views
11

Beynimi arel ve arkasındaki ilişkisel cebir etrafında bükmek için elimden gelenin en iyisini yapıyorum, ancak bir SELECT DISTINCT'u nasıl temsil ettiğimi sürekli olarak kavrayışımdan kurtulmaktır. Herkesin nasıl yapılacağını açıklayabilir:Arel/ilişkisel cebir ile farklı değerler nasıl elde edilir

SELECT DISTINCT title FROM posts; 

Çok teşekkürler!

+1

ben Arel bilmiyorum ama CJDate tarafından "Derinlik Veritabanı" benim okuma, ilişkisel cebir bir sorgunun sonucu bir dizi Tuplelerin. Yani eğer bu teoriyi takip ederse, bu varsayımdan daha farklı olmalıdır. –

cevap

1

Post.select('DISTINCT title')

Güncelleme 1: yazının zamanda

, bu Arel mevcut değildi. Bugünlerde ActiveRecord :: QueryMethods uniq yöntemi (http://apidock.com/rails/ActiveRecord/QueryMethods/uniq) vardır, bu nedenle isterdim:

Post.select(:title).uniq 

Güncelleme 2: Arel şimdi bu davranışı destekler gibi görünüyor. @maerics doğru cevabı vardır. Kabul edilen cevap olmasaydı bunu silecektim.

+0

Tam olarak cebirsel değil, ancak verimliliği ile tartışmak zor ;-) – jemmons

+2

Bu yaklaşımla ilgili önemli bir sorun var: select ifadesiyle birden çok kapsamınız varsa, bunları bir araya getirmek geçersiz SQL'e neden olabilir. –

+5

Bu AREL değildir ve bu nedenle soruyu cevaplamaz. –

6

Önceki cevap Rails yolu, değil mi? Arel yolu değil.

Bu 1.x için çalışır:

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

orada API aracılığıyla bunu yapmanın başka "daha doğru" yolu ama henüz o çözemedim tahmin ediyorum.

+4

Bu şimdi çalışmıyor gibi gözüküyor. –

+1

Bu doğrudur. Bu cevap Arel 1.x içindi ve artık çalışmayacak. – numbers1311407

+1

Alternatifin ne olduğunu biliyor musun? –

3

Bir kapsamı kullanarak yapıyorsanız:

AREL her zaman operasyon içinde SET kullandığından
scope :recent, lambda {|count| 
    select("DISTINCT posts.*"). 
    joins(:whatever). 
    limit(count). 
    order("posts.updated_at DESC") 
    } 
0

, yinelenen satır sonuçları otomatik olarak silinir. Sadece normal bir proje (Phi) işlemi kullanın.

+0

Bu teoride güzel bir fikir ama gerçekte açıkçası yanlıştır. Arel sorguları, "ayrı" yöntemle açıkça kısıtlanmadığı sürece, herhangi bir projeksiyonda yinelenen girdileri döndürür. – maerics

12

"farklı" bir yöntem yoktur saf Arel (değil Raylar/ActiveRecord) kullanarak:

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

İlginçtir ki, "ayrı" yöntemi diğer Arel yöntemlere göre, chainable değildir.

+0

Bir süredir bunun için arıyorum, çok teşekkürler! – Joe

+0

Arel sürümü, '5.0.1' ile, bu artık çalışmıyor :(. –

+1

Arel 6, her şey mükemmel çalışır.Ayrıca, SelectManager'ı döndürürken zincirlenebilir, – Slotos

8

bunu yapmak için Arel yoludur:

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

'sayım (true)' kullandığım halde Arel 3 için harika çalışıyor –

İlgili konular