Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/11.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
Ruby Rails复杂SQL,带有聚合函数和DayOfWeek_Sql_Ruby On Rails_Aggregate_Dayofweek - Fatal编程技术网

Ruby Rails复杂SQL,带有聚合函数和DayOfWeek

Ruby Rails复杂SQL,带有聚合函数和DayOfWeek,sql,ruby-on-rails,aggregate,dayofweek,Sql,Ruby On Rails,Aggregate,Dayofweek,轨道2.3.4 我搜索过谷歌,但没有找到我的困境的答案 对于这个讨论,我有两个模型。用户和条目。用户每天可以有多个条目 条目具有值,并在日期发送 我想查询并显示用户在一周中每天的条目平均值。因此,如果用户输入了过去3周的值,我想在MySQL中显示周日、周一等的平均值,很简单: SELECT DAYOFWEEK(sent_at) as day, AVG(value) as average FROM entries WHERE user_id = ? GROUP BY 1 该查询将返回0到7条记录

轨道2.3.4

我搜索过谷歌,但没有找到我的困境的答案

对于这个讨论,我有两个模型。用户和条目。用户每天可以有多个条目

条目具有值,并在日期发送

我想查询并显示用户在一周中每天的条目平均值。因此,如果用户输入了过去3周的值,我想在MySQL中显示周日、周一等的平均值,很简单:

SELECT DAYOFWEEK(sent_at) as day, AVG(value) as average FROM entries WHERE user_id = ? GROUP BY 1
该查询将返回0到7条记录,具体取决于用户至少有一条记录的天数

我已经查看了find_by_sql,但在搜索条目时,我不想返回条目对象;相反,我需要一个最多7天的数组和平均值


此外,我还担心它的性能,因为我们希望在用户登录时将其加载到用户模型中,以便它可以显示在他们的仪表板上。欢迎提供任何建议/建议。我对Rails比较陌生。

未经测试,但类似的东西应该可以工作:

@user.entries.select('DAYOFWEEK(sent_at) as day, AVG(value) as average').group('1').all
注意:使用select显式指定列时,返回的对象是只读的。Rails无法可靠地确定哪些列可以修改,哪些列不能修改。在这种情况下,您可能不会尝试修改所选列,但也可以通过结果对象修改sent_at或value列

以一种相当新的友好的格式查看,以了解这里正在发生的事情。哦,如果这个查询不起作用,请发回,这样其他可能偶然发现这个的人可以看到,我可能可以更新

由于条目返回数组,这将不起作用,因此我们可以尝试改用join:

User.where(:user_id => params[:id]).joins(:entries).select('...').group('1').all

再说一次,我不知道这是否有效。通常您可以指定连接后的位置,但我还没有在其中看到select组合。这里有一个棘手的问题,select可能根本不会返回任何关于用户的数据。在条目模型中编写一个只使用select_all调用查询并跳过关联映射的方法,而不使用find_by_*方法可能更有意义。

您可以直接查询数据库,无需使用实际的ActiveRecord对象。例如:

ActiveRecord::Base.connection.execute "SELECT DAYOFWEEK(sent_at) as day, AVG(value) as average FROM entries WHERE user_id = #{user.id} GROUP BY DAYOFWEEK(sent_at);" result = Rails.cache.fetch('user/#{user.id}/averages', :expires_in => 1.day) do # Your sql query and results go here end 这将为您提供一个MySql::Result或MySql2::Result,然后您可以使用此可枚举文件上的每个或所有内容来查看结果

至于缓存,我建议使用memcached,但任何其他rails缓存策略也可以。memcached的好处是,您可以让缓存在一段时间后过期。例如:

ActiveRecord::Base.connection.execute "SELECT DAYOFWEEK(sent_at) as day, AVG(value) as average FROM entries WHERE user_id = #{user.id} GROUP BY DAYOFWEEK(sent_at);" result = Rails.cache.fetch('user/#{user.id}/averages', :expires_in => 1.day) do # Your sql query and results go here end
这将把您的结果放入memcached中,在“user//averages”键下保存一天。例如,如果您是id为10的用户,您的平均值将在“user/10/average”下的memcached中,下次您在同一天内执行此查询时,将使用缓存的版本,而不是实际访问数据库。

通过进一步研究和调整,我发现这会起作用:@ee=Entry.all:select=>dayofweekentries.sent\u at as Day,avgentries.value as value,:group=>dayofweeksent\u at,:conditions=>['user\u id=?',self.id]虽然看起来很难看,但可能效率不高。我将回顾我得到的答案,看看它们是否更好。我真的很喜欢这个外观,但它给出了一个错误:ArgumentError:0Ahh的参数数目错误1,是的,我认为@user.entries将返回一个数组,而不是ActiveRecord::Relation。使用另一个可能的选项进行更新…使用Rails 2.3.4。是的,Rails 3在哪里?NoMethodError:未定义的方法“where”我用另一个答案得到了它,但我非常感谢你的帮助!ActiveRecord直接数据库查询确实有效。与条目相比,使用直接数据库查询在开销方面是否有优势。我在上面对原始问题的评论中使用的所有查询?这实际上取决于您希望如何处理结果。这只是偏好和格式的不同。在我看来,我不喜欢将一个对象与聚合查询中的数据混合在一起。当我可以使用字符串和数字数组时,没有理由用不相关的数据实例化条目对象。我同意不要用不相关的数据实例化对象。我想我会使用直接查询方法。谢谢你的帮助。