¿Cómo agrupar el resultado de una consulta con un registro activo?

Tengo el siguiente modelo:

ProfileViews (id, user_id, viewer_id)

I am trying to return all user_views, which are grouped by viewer_id ... Note viewer_id can nil, which is something I want to return. I can say viewed 20 times by nil etc...

¿Por qué esto no funciona?

@profile_views = ProfileView.select('*').where(:user_id => current_user.id).group(:viewer_id)   

preguntado el 10 de marzo de 12 a las 00:03

2 Respuestas

Your query doesn't work because you're using PostgreSQL (or some similarly strict database) and your SELECT list doesn't match your GROUP BY. Everything in your SELECT must either be inside an aggregate function (such as COUNT, AVG, ...) or it must appear in your GROUP BY clause; some databases, such as MySQL and SQLite, will take a guess to remove the ambiguity but other databases, such as PostgreSQL, will not. I'd guess that you're seeing an error similar to:

ERROR:  column "X" must appear in the GROUP BY clause or be used in an aggregate function

You're probably looking for something more like this:

@profile_views = ProfileView.where(:user_id => current_user.id)
                            .count(:group => :viewer_id)

That will give you a simple Hash in @profile_views que mapas viewer_id disponibles (Incluyendo nils) to the number of views.

That bit of AR is equivalent to this SQL:

select viewer_id, count(*)
from profile_views
where user_id = #{current_user.id}
group by viewer_id

You'll note that everything in the SELECT is either in the GROUP BY or an aggregate.

You can't get the ProfileView objects at the same time as the counts. When you add a GROUP BY, you're collapsing rows that have the same viewer_id and once the rows have lost their identities, there is no way for the database to choose which row should be used to instantiate the ProfileView.

respondido 10 mar '12, 01:03

I do not think you can have select(*) in a group statement. You might try select count(viewer_id) or whatever grouping you are going for.


Puedes ver más ejemplos aquí

respondido 10 mar '12, 00:03

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.