Group by i count

Witam,

Byc moze prosty problem ale jakos nie moge sobie poradzic:

model Query ma pola string i date. jest wiele wystapien tego samego stringa.
Chcialbym otrzymac liste Query wraz z iloscia wystapien.
Probowalem czego takiego:
Query.find_by_sql(‘select string, count(*) as count from squeries groub by string’) ale pola count nie ma w zwroconych obiektach

jakies pomysly?

dzieki
martin

Możesz użyć metody count_by_sql w klasie ActiveRecord:
http://api.rubyonrails.com/classes/ActiveRecord/Base.html#M001386

Ale w tym przypadku powinnien wystarczyć moduł ActiveRecord::Calculations
http://api.rubyonrails.org/classes/ActiveRecord/Calculations/ClassMethods.html

Pozdrawiam

a konkretnie która metoda?

Za takie pytanie powinieneś zostać odesłany do kąta. Znaczy, nawet nie otworzyłeś linków jakie vitotao Ci podał…

Do kąta to możesz odesłać swoją starą. Zadna z metod w ActiveRecord::Calculations nie robi tego co pytałem

martinciu: otwierasz pierwszy link - czytasz - używasz swojego zapytania w odpowiedni sposób i jest.

Drugi link - masz rację - nie był adekwatny (bardziej w celach informacyjnych), co nie zmienia faktu, że miast kłócić się powinniśmy zająć sie czymś produktywnym.

no nie bardzo, count_by_sql zwraca integera a nie array’a obiektow z dodatkowym polem

sql = ActiveRecord::Base.connection(); sql.select_rows( "select string, count(*) from squeries group by string" )

Jeśli Ci coś nie pasuje to nie musisz korzystać z tego forum. Nikt tutaj łaski Ci nie robi a tylko z własnej dobrej woli poświęca czas, więc się opanuj… albo wracaj skąd przyszedłeś. 12 latków używających takich obraźliwych haseł tutaj nam nie potrzeba.

@Tomash: Zamiast wysyłać ludzi do kąta byłoby lepiej gdybyś podał prostą odpowiedź na proste pytanie. Powinienem Cię za to wysłać do kąta :slight_smile:

@martinciu:

Możesz to zrobić na kilka sposobów:

Query.find_by_sql('SELECT string, count(*) AS `count` FROM queries GROUP BY string')

zwraca tablicę obiektów klasy query, np.:

[#<Query string: "dupa">, #<Query string: "orzech">]

Do count’a dostajesz się wywołując metodę .count, eg.

Query.find_by_sql('SELECT string, count(*) AS `count` FROM queries GROUP BY string').first.count

zwróci np. “3” jako typ string, więc potrzebujesz:

Query.find_by_sql('SELECT string, count(*) AS `count` FROM queries GROUP BY string').first.count.to_i

Możesz to też zrobić przy pomocy metod, które podesłał vitotao, np:

Query.count(:all, :group => :string)

zwróci np.:

[["dupa", 1], ["orzech", 2]]

(czyli tablica tablic gdzie pierwszym elementem jest wartość kolumny :group, a drugim wartość count (integer w tym wypadku)

Istnieje kilka sposobów, wybierasz ten który Ci najbardziej odpowiada.

Dzięki.
Zanim tu napisalem sporobowalem pierwszego sposobu, ale jak " [#<Query string: “dupa”>, #<Query string: “orzech”>] " to nie pomyslalem zeby sprowac czy instnieje count w kazdym obiekcie

Witam wszystkich,

Podepnę się pod ten wątek z następującym problemem:

Posiadam modele: “Album”, “Category” połączone relacją “has_and_belongs_to_many”. Chciałbym uzyskać z bazy nazwy wszystkich kategorii wraz z ilością albumów, które należą do każdej z nich. Zastosowałem takie coś:

@count = Category.count(:all, :group => :category_id, :joins => :albums)

Otrzymując coś w stylu:

--- !map:ActiveSupport::OrderedHash "1": 2 "2": 1 "3": 2 "4": 1 "5": 1
Wartości się zgadzają, natomiast chciałbym zamiast id kategorii otrzymać jej nazwę (pole ‘title’). Czy da się to zrobić jednym zapytaniem czy też trzeba tworzyć nową kolekcję z połączeń dwóch zapytań: powyższego i “Category.all” ?

Witam,

Posiadam takie zapytanie, które wyciąga mi 5 najwięcej skomentowanych albumów (korzystam z acts_as_commentable), sortując je od razu od najwyższej do najniższej wartości:

 most_commentable = Comment.published.count(:conditions => { :commentable_type => 'Album' }, :group => 'commentable_id', :limit => 5).sort { |a,b| b <=> a}

Z powyższego zapytania otrzymuję tablicę tablic typu [ [2,4], [1,2] ] gdzie klucz to id albumu, a wartość to ilość komentarzy (jak widać posortowane tak jak chciałem).

Do tego miejsca wszystko jest ok. Chciałbym teraz pobrać z bazy te albumy takim zapytaniem (czyli według ID z poprzedniej posortowanej tablicy most_commentable):

 @albums = Album.find(most_commentable.collect {|a| a[0] })

Niestety cały czas pobiera mi te albumy w kolejności wg ID albumu, a nie według kolejności z tablicy most_commentable. Czy ktoś wie gdzie leży problem lub zna lepsze rozwiązanie powyższego (bo na pewno takowe istnieje)?

Z góry dziękuję za pomoc.

Ja bym to napisał tak (pisane z pamięci, więc nie gwarantuję, że zadziała):

@albums = Album.all(:joins => :comments, :group => "albums.id", :order => "COUNT(comments.id) DESC", :limit => 5)

czyli zrezygnowałbym z wyciągania najpierw samych id albumów i zamiast tego wyciągnął szukane albumy w jednym zapytaniu.

I to jest idealne rozwiązanie, którego poszukiwałem. Dzięki bardzo!