当前位置: 首页 > 面试题库 >

在MySQL或Rails中在特定日期范围内每天获取AVG的最佳方法

孟文栋
2023-03-14
问题内容

我正在尝试在Rails中绘制图表,例如在给定日期范围内每天的平均销售量

假设我有一个products_sold模型,该模型具有“ sales_price”浮动属性。但是,如果某天没有销售(例如,model /
db中没有销售),我只想返回0。

MySQL / Rails中完成此任务的最佳方法是什么?我知道我可以做这样的事情:

此SQL查询可能也是获得我想要的东西的完全错误的方法

SELECT avg(sales_price) AS avg, DATE_FORMAT(created_at, '%m-%d-%Y') AS date
    FROM products_sold WHERE merchant_id = 1 GROUP BY date;

并获得如下结果:

| 平均| 日期|
  23 01-03-2009
  50 2009年1月5日 
  34 2009年1月7日
  ……

我想要得到的是:

| 平均| 日期|
  23 01-03-2009
   0 01-04-2009
  50 2009年1月5日
   0 01-06-2009 
  34 2009年1月7日
   0 01-08-2009
  ……

我可以使用SQL来执行此操作,还是必须对结果进行后处理以查找日期范围中哪些日期不在SQL结果集中?也许我需要一些子选择或IF语句?

感谢大家的帮助。


问题答案:

是否有一个原因(除了已经提到的日期以外)为什么您不使用ActiveRecord中的内置组功能?您似乎担心“后处理”,我认为这并不是真正要担心的事情。

您正在使用Rails,因此您可能应该首先寻找Rails解决方案[1]。我的第一个想法是做类似的事情

Product.average(:sales_price, :group => "DATE(created_at)", :conditions => ["merchant_id=?", 1])

哪个ActiveRecord变成了您描述的SQL。假设has_many在商家和产品之间存在已声明的关联,那么使用它可能会更好,因此类似:

ave_prices = Merchant.find(1).products.average(:sales_price, :group => "DATE(created_at)")

(我希望您对模型的描述为“ products_sold”是一种转录错误,顺便说一句-如果不是,则您对类的命名有些不满!)

毕竟,您回到了起点,但是您以更传统的Rails方式到达了那里(Rails确实重视约定!)。现在我们需要填补空白。

我假设您知道您的日期范围,假设它被定义为从from_date到的所有日期to_date

date_aves = (from_date..to_date).map{|dt| [dt, 0]}

这样就将日期的完整列表构建为一个数组。我们不需要平均日期:

ave_price_dates = ave_prices.collect{|ave_price| ave_price[0]} # build an array of dates
date_aves.delete_if { |dt| ave_price.dates.index(dt[0]) } # remove zero entries for dates retrieved from DB
date_aves.concat(ave_prices)     # add the query results
date_aves.sort_by{|ave| ave[0] } # sort by date

那很多东西对我来说显得有些混乱:我认为它可能更简洁更干净。我会研究构建一个Hash或Struct,而不是停留在数组中。

[1]我并不是说不使用SQL,而是在ActiveRecord无法生成最有效的查询而您又回过头来的情况下发生find_by_sql。很好,应该是这样,但是我认为您应该尝试仅将其用作最后的手段。



 类似资料:
  • 问题内容: 动态创建日期范围以便与报表配合使用的最佳方法。 因此,如果给定的一天没有活动,我可以避免报表上的空行。 通常是为了避免此问题:在sql结果中(在mysql或perl端)填充空日期的最直接方法是什么? 问题答案: 在MySQL中,没有直接的方法可以做到这一点。最好的选择是用您选择的服务器端语言生成一个daterange数组,然后从数据库中提取数据,并使用date作为键将结果数组与date

  • 问题内容: 我想问一下在两个日期之间搜索数据的最有效(最快)方法是什么? 让我们考虑以下简单查询: “ Date_”列是DATETIME类型。 我尝试了不同的选择,例如: 和 和 实际上,此Select查询要复杂得多(具有联接和更多条件)。这只是简化版本。根据EXPLAIN,查询的执行方式没有区别。我需要说Date_列已建立索引。不幸的是,我无法测试实际的查询速度,因为我无法避免操作系统缓存,但是

  • 问题内容: 假设我有个约会2013年6月20日 如何获取上周的日期范围,即本例中的6月9日至6月15日。 另外,如果日期是2013年6月2日 范围应该是5月26日至6月1日 问题答案: 这是基于Java日历的解决方案 输出 它已本地化,在我的“语言环境”周中,从星期一开始

  • 问题内容: 我最近遇到了一项任务,必须在日期范围内获得所有星期五。我写了一小段代码,很惊讶地看到一些奇怪的行为。 下面是我的代码: 现在,当我运行代码时,我注意到缺少2011年的星期五。经过一些调试和在线浏览后,我发现这是特定于区域设置的,我必须使用它来修复它。 因此,在上面的代码中未注释相关行。 据我了解,一年的第一周应该从一年的整个星期开始。 例如,2010年1月1日是星期五。但它不会显示在结

  • audit_modifier是VARCHAR2(30个字符),并且audit_modifier值以以下格式存储[2018-01-18T17:19:47.285z]。 从TO_DATE('2018-01-16','yyyy-mm-dd')和TO_DATE('2018-01-16','yyyy-mm-dd')之间的trunc(audit_modifier)的表中选择*; ORA-00932:不一致的数

  • 问题内容: 使用SQL时,是否可以在提供范围的列中插入随机的datetime值? 例如,给定范围为 我对范围部分感到困惑。正如我将要做的 问题答案: 这是一个应该有所帮助的示例: 它使用日期作为基础,将其转换为Unix时间戳,并向基础日期添加0到+2年的随机秒数,并将其转换回DATETIME。 它应该很接近,但在更长的时间内会leap年,其他调整会使其失效。