Rails 3 ActiveRecord:顺序和按关联计数分组
技术问答
225 人阅读
|
0 人回复
|
2023-09-14
|
给定模型所在的相同场景 y! K, k$ v4 s1 E2 J, \
Song has many :listens, P, W7 v ^5 G0 \
我想按收听次数对歌曲进行分组。我的目标是查看歌曲与听音的分布情况。就像是…( X" ?4 p* N5 I! w
song_listen_distribution = {0 => 24, 1 => 43, 2=>11, ... MAX_LISTENS => 1}+ i3 m- J* W1 K% ]* x( M
这样就song_listen_distribution[4]可以返回听过4次的歌曲数量。" }3 Q, w8 t7 R, a. j4 t
上面链接问题的公认答案非常接近我,但是我无法按“ songs.listens_count”分组& z+ v3 l3 i; p4 {
Song.select("songs.id, OTHER_ATTRS_YOU_NEED, count(listens.id) AS listens_count").% m; i3 x) e& b
joins(:listens).
K1 r: S2 ]# M% W% o# z group("songs.listens_count").' }! f( Y, Z: q G8 O" A1 b7 y
order("listens_count DESC")9 B& s9 M' A: i
/ n& ~4 [" P5 X( K9 \; c解决方案:. L F( s9 U, J+ r" _
) I+ \5 J$ H" _6 q% w
. k' u+ ?) V4 e; c5 _( Y, K4 W( L4 o& Z l& O: V7 C( ~/ W5 T5 a2 F$ O
您正在寻找的内容与标准ActiveRecord查询的映射并不理想。$ S& W. P& Z+ z! o
您可以调用直接SQL来最有效地获取所需内容:
, \" z3 W0 F' b9 Z3 {0 s4 x, |subquery = Song.joins(:listens).group(:id).select("songs.id, COUNT(*) as listen_count).to_sql
( i% E& B1 ]- C1 V( m6 d* N9 Xraw = Song.connection.select_rows("SELECT listen_count, COUNT(*) FROM (#{subquery}) t GROUP BY listen_count ORDER BY listen_count DESC")
, J! e5 Z0 |# B$ w+ Qsong_listen_distribution = Hash[raw]
1 P0 M- h C7 j! |$ U S另外,您可以使用ActiveRecord查找所有歌曲的计数,然后在ruby中建立发行字典:
% L& f# l$ _: y7 u1 lsong_listens = Song.joins(:listens).group(:id).count$ f8 t4 B O$ _6 c* _5 S
song_listen_distribution = song_listens.group_by{|n| n.last}.( {$ W' R& T8 g% g( M& w' a- |
each_with_object({}){|(k, g), h| h[k] = g.size} |
|
|
|
|
|