sen yapamaz basit .group(:name)
size gruplanmamış ve unaggregate seçeceğiniz için zaman senin SQL bir GROUP BY name
ürettiği için
When GROUP BY is present, it is not valid for the SELECT list expressions to refer to ungrouped columns except within aggregate functions, since there would be more than one possible value to return for an ungrouped column.
böyle bir şey ile gruplamaya fazla sütun ekleme başlatırsanız:
T.group(T.columns.collect(&:name))
sonra tarafından gruplama olacak hangi satırı almak ve PostgreSQL (rightly IMHO) complains gerektiği konusunda d sütun, bu belirsizliğe yol açar istemediğiniz şeyler ve tüm masayı çekip bitirirsiniz ve bu sizin istediğiniz şey değildir. Gruplama probleminden kaçınmak için bir araya getirmeye çalışırsanız, farklı satırları karıştırarak sonuçlanırsınız (yani, bir satır diğer satırdan başka bir sütun gelirken bir sütun gelir) ve bu da sizin istediğiniz gibi değildir.
ActiveRecord gerçekten bu tür bir şey için oluşturulmamış, ancak biraz çaba ile isteğinize boyun eğebilirsiniz.
AR kullanıyorsunuzdur, dolayısıyla muhtemelen bir id
sütununa sahipsiniz. PostgreSQL 8'iniz varsa.4 ya da daha yüksek, daha sonra window functions yerel olarak GROUP BY; iki kez pencereye ihtiyacın olacak: bir kez name
/thedate
çiftini anlamaya ve sadece bir tane id
(sadece aynı name
ve thedate
ile eşleştiğinde, en eski thedate
ile eşleşecek) ve böylece benzersiz bir satır olsun :
select your_table.*
from your_table
where id in (
-- You don't need DISTINCT here as the IN will take care of collapsing duplicates.
select min(yt.id) over (partition by yt.name)
from (
select distinct name, min(thedate) over (partition by name) as thedate
from your_table
) as dt
join your_table as yt
on yt.name = dt.name and yt.thedate = dt.thedate
)
Sonra find_by_sql
o sarın ve size nesneleri var.
Heroku'yu paylaşılan bir veritabanıyla (veya 8.4 veya üstü olmayan başka bir ortamla) kullanıyorsanız, PostgreSQL 8.3 ile sıkışmışsınız ve pencere işlevleriniz olmayacaktır. Bu durumda, muhtemelen Yakut-arazi çiftleri filtrelemek isterdim:
with_dups = YourTable.find_by_sql(%Q{
select yt.*
from your_table yt
join (select name, min(thedate) as thedate from your_table group by name) as dt
on yt.name = dt.name and yt.thedate = dt.thedate
});
# Clear out the duplicates, sorting by id ensures consistent results
unique_matches = with_dups.sort_by(&:id).group_by(&:name).map { |x| x.last.first }
sonra 8.3 uyumlu çözüm olabilir yinelenen name
/min(thedate)
çiftleri orada olmayacak eminseniz en iyi bahşin ol; Ancak, çok fazla kopya olacaksa, o zaman veritabanının, attığınız binlerce AR nesnesini oluşturmaktan kaçınmak için mümkün olduğunca fazla iş yapmasını istiyorsunuz. Belki daha güçlü PostgreSQL-Fu'lu bir başkası yanımda gelecektir ve daha güzel bir şey sunacaktır.
Bir "isim, min (tarih) çifti" tablosunda iki kez gösteriliyorsa, bunun benzersiz sorunları vardır. –