Rails计数记录而不再查询

说我查询表

rawStats = Stats::TrackProcessed.select("token") 

并收到表中所有令牌的数量。

看起来像这样:

 3e79a387c29bda1069271e06ad03d82b8296242e 059681f46ab1c1fa8cf8443a82f0898172e0b646 eacd846ea4e91b49f92f416f61e0f2d075b9dae7 eacd846ea4e91b49f92f416f61e0f2d075b9dae7 811705019a970929801adbf3db0ede31ed01816c 

我需要返回一个看起来像这样的哈希列表

 { '3e79a387c29bda1069271e06ad03d82b8296242e' => 1, '059681f46ab1c1fa8cf8443a82f0898172e0b646' => 1 'eacd846ea4e91b49f92f416f61e0f2d075b9dae7' => 2 '811705019a970929801adbf3db0ede31ed01816c' => 1 } 

第一个值是标记,第二个值是表中该标记的出现次数。 然后我需要从所有记录中获得平均值。

到目前为止,我已经查询了表

 rawStats = Stats::TrackProcessed.select("distinct token") 

通过检索唯一的令牌

然后,每个循环计算每个令牌的出现次数

 rawArr = [] rawStats.each do |r| token = { :token => r.token, :count => rawStats.where("token = ?",r.token).count('token') } rawArr << token end 

但这个过程就像

 (0.7ms) SELECT COUNT(`stats_track_processed`.`token`) FROM `stats_track_processed` WHERE `stats_track_processed`.`token` = '196e595b573f71fc2af04693c73809303bebd62d' (0.7ms) SELECT COUNT(`stats_track_processed`.`token`) FROM `stats_track_processed` WHERE `stats_track_processed`.`token` = 'db67ab44e94ca338d90e902a36c37b4998a47ff0' (0.7ms) SELECT COUNT(`stats_track_processed`.`token`) FROM `stats_track_processed` WHERE `stats_track_processed`.`token` = 'a8a78cffc0935b07f90b5f3008dcad27e8ac71c7' (0.8ms) SELECT COUNT(`stats_track_processed`.`token`) FROM `stats_track_processed` WHERE `stats_track_processed`.`token` = '91b8ae5ffa12ece30d8548b488fab8aff7614f2b' (0.7ms) SELECT COUNT(`stats_track_processed`.`token`) FROM `stats_track_processed` WHERE `stats_track_processed`.`token` = '649e7aa59cc8af6c59cec1cf637ffed1ce6b3be7' (0.7ms) SELECT COUNT(`stats_track_processed`.`token`) FROM `stats_track_processed` WHERE `stats_track_processed`.`token` = '441dae6f22776687b57daaaeef2c63c31902b987' (0.7ms) SELECT COUNT(`stats_track_processed`.`token`) FROM `stats_track_processed` WHERE `stats_track_processed`.`token` = '6b8937a13012f22c8a4cdd4ed4caad0ad8761d3b' (0.6ms) SELECT COUNT(`stats_track_processed`.`token`) FROM `stats_track_processed` WHERE `stats_track_processed`.`token` = 'beaba154f38d5c9b64e4fb2d851ec785bd6bc4ec' (0.6ms) SELECT COUNT(`stats_track_processed`.`token`) FROM `stats_track_processed` WHERE `stats_track_processed`.`token` = 'efa9f3a71c4ff33abcae4af788ef6d0be599f76a' (0.7ms) SELECT COUNT(`stats_track_processed`.`token`) FROM `stats_track_processed` WHERE `stats_track_processed`.`token` = '053a7727885f3c4099a9b31a2eccc77b99df50ee' (0.7ms) SELECT COUNT(`stats_track_processed`.`token`) FROM `stats_track_processed` WHERE `stats_track_processed`.`token` = '32dc984c9f85ff91242533144cd179a9b4529bed' (0.7ms) SELECT COUNT(`stats_track_processed`.`token`) FROM `stats_track_processed` WHERE `stats_track_processed`.`token` = 'a58804ae38490f08a1645c8271e88df3757fe771f' (0.7ms) SELECT COUNT(`stats_track_processed`.`token`) FROM `stats_track_processed` WHERE `stats_track_processed`.`token` = 'a58804a2e38490f08a1645c8271e88df3757fe771f' 

通过在处理大量数据时单独查询每个令牌,这看起来非常糟糕。

我已经通过SQL查询完成了这个,看起来像这样

 SELECT AVG(viewsAverage) as total FROM (SELECT COUNT(token) AS viewsAverage FROM stats_track_processed WHERE admedia_id = #{params[:admedia_id]} AND #{params[:banner_id]} AND (access_time BETWEEN '#{params[:begin]}' AND DATE_ADD('#{params[:end]}', INTERVAL 1 DAY)) GROUP BY token) stats_track_processed 

但这真的看起来像一个糟糕的解决方案,我现在正在重构代码并将所有逻辑移动到控制器。

任何帮助都感激不尽。

先感谢您。

迭代完整列表并维护计数的哈希值。

 result = Stats::TrackProcessed.select("token") counts = Hash.new{|h,k| h[k] = 0 } result.each{|el| counts[el] +=1} 

然后得到一个平均值,你可以做类似的事情

  average = counts.values.inject(0){|sum, el| sum + el} / counts.length 

试试这个

  Stats::TrackProcessed.select(:token).count(group: :token) 

干杯。

您可以在单个查询中执行此操作:

 SELECT SUM(IF(token = '196e595b573f71fc2af04693c73809303bebd62d', 1, 0)) AS token_1, SUM(IF(token = 'db67ab44e94ca338d90e902a36c37b4998a47ff0', 1, 0)) AS token_2, ... FROM `stats_track_processed` WHERE `stats_track_processed`.`token` IN('196e595b573f71fc2af04693c73809303bebd62d', 'db67ab44e94ca338d90e902a36c37b4998a47ff0', ...); 

要么

 SELECT token, COUNT(token) AS token_count FROM stats_track_processed GROUP BY token;