mysql - .where 中两个日期之间的差异

标签 mysql ruby-on-rails ruby-on-rails-4

这是我的逻辑 我想获得最接近特定手机 @mobile 的 4 款更昂贵的手机,但在一种情况下,两款手机的发布日期之间的差异不超过一年半 这是查询

high = Mobile.where("price >= #{@mobile.price} AND id != #{@mobile.id} AND visible = true").where("ABS(release_date - #{@mobile.release_date}) > ?", 18.months).order(price: :ASC).first(4)

第一个 .where() 工作正常,但第二个不工作,我得到这个错误

Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '00:00:00 UTC) > 46656000) ORDER BY `mobiles`.`price` ASC LIMIT 4' at line 1: SELECT `mobiles`.* FROM `mobiles` WHERE (price >= 123123.0 AND id != 11 AND visible = true) AND (ABS(release_date - 2016-04-10 00:00:00 UTC) > 46656000) ORDER BY `mobiles`.`price` ASC LIMIT 4

我想现在您可以理解我的逻辑了。实现它的正确语法是什么?

最佳答案

这里有一些提示:

  • 使用“#{}” 运算符将变量连接到您的查询中是一种危险的做法。这样做会绕过查询参数化,并可能使您的应用程序对 SQL injection 开放.相反,请在您的 where 子句中使用 "?"
  • MySQL 给您错误的原因是您将一个字符串连接到您的查询中,而没有将其封装在引号中。

考虑到这两点,我会像这样重构您的查询:

high = Mobile.where("price >= ?", @mobile.price)
         .where.not(id: @mobile.id)
         .where(visible: true)
         .where("ABS(release_date - ?) > 46656000", @mobile.release_date)
         .order(price: :ASC).first(4)

您会注意到我将 18.months 替换为 46656000。这在 Rails 应用程序中节省了几个时钟周期。根据您的数据库模式,最后一个 where 子句可能不起作用。下面的修改可能最终会更好地工作。

作为进一步的改进,您可以重构最后一个 where 子句以查找介于 @mobile.release_date 之前 18 个月和之后 18 个月之间的发布日期。这使您的 MySql 数据库不必对每条记录进行数学运算,并可能带来更好的性能:

.where(release_date: (@mobile.release_date - 18.months)..(@mobile.release_date + 18.months) )

我不知道你的数据库架构,所以你可能会遇到上面代码的日期转换问题。我建议您在 Rails 控制台中使用它。

关于mysql - .where 中两个日期之间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47147522/

相关文章:

ruby-on-rails-4 - 导轨 : How to use i18n with Rails 4 enums

ruby-on-rails - 使用部分而不是助手渲染表单?

ruby-on-rails - Ruby on Rails : Once you've eager loaded an association that has conditions, 如何在不再次接触数据库的情况下获取它?

ruby-on-rails - Rails 4 HABTM 自定义关联验证

java - 在 Java 中更新 mysql 数据库

mysql - InnoDb Mysql表的行大小限制

python - django.db.utils.OperationalError : (1045:Access denied for user 'root' @'localhost' (using password: NO)

php - 存储 HABTM 协会中持有的项目的排序顺序 - CakePHP

ruby-on-rails - 名称错误 : uninitialized constant TurboDevAssets

ruby-on-rails - rails ActiveSupport :Concern and Private Methods