Order by over a Count in another table

1

I wanted to sort a table of items by counting the positive (other table) ratings for that item. This query will be run in controler : item: index

Item:
  id
  nome

Avaliacao
  id
  item_id
  avaliacao[0 negativo, 1 positivo]

For example:

Banda 1 - <15 positivos> <3 negativos>
Banda 2 - <10 positivos> <30 negativos>
Banda 3 - <5 positiva> <0 negativas>
Banda 4 - <0 positiva> <0 negativas>
Banda 5 - <0 positiva> <0 negativas>
Banda 6 - <0 positiva> <0 negativas>
Banda 7 - <0 positiva> <0 negativas>
...
    
asked by anonymous 09.05.2014 / 03:49

2 answers

2

Taking advantage of the answer from @bfavaretto, if you have in Avaliacao a belongs_to :item , you should do the following for #:

ruby-on-rails
Item.joins(:avaliacaos).group("avaliacaos.item_id").order("sum(avaliacaos.avaliacao) desc")

Otherwise, it will be necessary to iterate over the elements of the Item

items = Hash.new
Item.all.each do |item|
  items[item.id] = Avaliacao.where('item_id = ? AND avaliacao = ?', item.id, 1).count
end
maiores_avaliacoes = items.sort_by { |k,v| v}.reverse

Where maiores_avaliacoes will be a vector of pairs in which the first element is the key and the second the number of positive evaluations, that is, maiores_avaliacoes[0] will return a vector with two positions where / em> will be the item_id of the item with the most positive ratings and the position 1 will be the number of positive ratings that that item has.

This should return only the items with ratings and that are positive.

How to count the number of positive and negative evaluations

Due to my inability with SQL queries, I will not know the query that should be made to return the number of positive or negative evaluations (though I suppose that count should be used instead of sum ) . However, you can achieve what you want by slightly modifying the second example, as follows:

avaliacoes = Hash.new
Item.all.each do |item|
  avaliacoes[item.id] = [Avaliacao.where('item_id = ? AND avaliacao = ?', item.id, 0).count, Avaliacao.where('item_id = ? AND avaliacao = ?', item.id, 1).count]
end
Item.all.each do |item|
  puts item.nome + " - <" + avaliacoes[item.id][1] + " positivas> <" + avaliacoes[item.id][1] + " negativas>\n"
end

This prints the data in the form you want, remembering that index 1 counts the number of positive ratings, while index 0 counts the negative >, saving them in Hash using item.id .

    
09.05.2014 / 12:53
0

The base is a query with JOIN between the two tables. You must also group by item, and sort by sum of ratings:

SELECT Item.id, Item.nome, SUM(Avaliacao.avaliacao) AS positivos
FROM Item
INNER JOIN Avaliacao
ON Avaliacao.item_id = Item.id
GROUP BY Item.id
ORDER BY SUM(Avaliacao.avaliacao) DESC
    
09.05.2014 / 04:21