Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql Rails无需再次查询即可计数记录_Mysql_Ruby On Rails_Ruby_Activerecord_Count - Fatal编程技术网

Mysql Rails无需再次查询即可计数记录

Mysql Rails无需再次查询即可计数记录,mysql,ruby-on-rails,ruby,activerecord,count,Mysql,Ruby On Rails,Ruby,Activerecord,Count,假设我查询了这个表 rawStats = Stats::TrackProcessed.select("token") 并接收表中所有令牌的数量 看起来像这样: 3e79a387c29bda1069271e06ad03d82b8296242e 059681f46ab1c1fa8cf8443a82f0898172e0b646 eacd846ea4e91b49f92f416f61e0f2d075b9dae7 eacd846ea4e91b49f92f416f61e0f2d075b9dae7 81170

假设我查询了这个表

rawStats = Stats::TrackProcessed.select("token")
并接收表中所有令牌的数量

看起来像这样:

3e79a387c29bda1069271e06ad03d82b8296242e
059681f46ab1c1fa8cf8443a82f0898172e0b646
eacd846ea4e91b49f92f416f61e0f2d075b9dae7
eacd846ea4e91b49f92f416f61e0f2d075b9dae7
811705019a970929801adbf3db0ede31ed01816c
我需要返回一个如下所示的哈希列表

{
   '3e79a387c29bda1069271e06ad03d82b8296242e' => 1,
   '059681f46ab1c1fa8cf8443a82f0898172e0b646' => 1
   'eacd846ea4e91b49f92f416f61e0f2d075b9dae7' => 2
   '811705019a970929801adbf3db0ede31ed01816c' => 1
}
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
其中第一个值是令牌,第二个值是表中该令牌的发生次数。 然后我需要从所有记录中得到这个的平均值

到目前为止,我已经了解了如何使用查询表

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
在处理大量数据时单独查询每个令牌,这看起来确实是一个非常糟糕的主意

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

{
   '3e79a387c29bda1069271e06ad03d82b8296242e' => 1,
   '059681f46ab1c1fa8cf8443a82f0898172e0b646' => 1
   'eacd846ea4e91b49f92f416f61e0f2d075b9dae7' => 2
   '811705019a970929801adbf3db0ede31ed01816c' => 1
}
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
但这看起来真的是一个糟糕的解决方案,我正在重构代码,并将所有逻辑移到控制器上

任何帮助都将不胜感激


提前感谢您。

您可以通过以下方式在一次查询中完成此操作:

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 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', ...);


遍历完整列表并维护计数的散列

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

遍历完整列表并维护计数的散列

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)
干杯。

试试这个

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


干杯。

我正在尝试将所有逻辑移到控制器,而不是SQL查询,我在SQL查询中完成了这项工作,它看起来真的像一个蹩脚的解决方案。我已经在我的问题上加了一条评论,以防你想看看我到目前为止得到了什么。另外,我真的不知道如何将此查询重写为活动记录。我认为您可以通过查询在单个组中执行所有这些操作,以获得更好的性能。我能够获得令牌哈希和出现次数:rawStats=rawStats。选择'token,counttoken作为token_count。组“token”现在只需要获得一个平均值。您在qs中更新的子查询将为您提供适当的平均值。是否使用activerecord或通过控制器逻辑执行此操作?我正在尝试将所有逻辑移到控制器而不是SQL查询,我在SQL查询中完成了这项工作,它看起来真的像是一个蹩脚的解决方案。我已经在我的问题上加了一条评论,以防你想看看我到目前为止得到了什么。另外,我真的不知道如何将此查询重写为活动记录。我认为您可以通过查询在单个组中执行所有这些操作,以获得更好的性能。我能够获得令牌哈希和出现次数:rawStats=rawStats。选择'token,counttoken作为token_count。组“token”现在只需要获得一个平均值。您在qs中更新的子查询将为您提供适当的平均值。是否使用activerecord或通过控制器逻辑执行此操作?查询很好,现在我只需要获得一个平均值。如果我可以通过对活动记录的单个查询来实现这一点,那就很好了。@screach-我编辑了我的回复,以包含如何在不返回数据库的情况下获得平均值的信息。查询很好,现在我只需要获得平均值。如果我能通过对活动记录的一次查询就可以做到这一点,那就太好了。@screach-我编辑了我的回复,以包含如何在不返回数据库的情况下获得平均值的信息。谢谢!这就是我想要的。这种方法可能比数据库中分组的任何方法都要慢。一个快速的BMBM显示,它的运行速度比PriteshJ在一张有25K条记录的矿井表上的解决方案慢三分之一左右。我猜随着线圈尺寸的增加,速度差距也会增大。谢谢!这就是我想要的。这种方法可能比数据库中分组的任何方法都要慢。一个快速的BMBM显示,它的运行速度比PriteshJ在一张有25K条记录的矿井表上的解决方案慢三分之一左右。我猜随着环路大小的增加,速度差距也会增大。