[英]rails difference between two dates inside .where
Here is my logic I want to get the closest 4 more expensive mobiles to a specific mobile @mobile
but under one condition the difference between the release dates of the two mobiles is not more than a year and half Here is the query 这是我的逻辑,我想将最昂贵的4个手机最接近特定的手机
@mobile
但在一种情况下,两个手机的发布日期之差不超过一年半。这是查询
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)
The first .where() works perfectly but the second is not working and I get this error 第一个.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
I think now you can get my logic. 我想现在您可以理解我的逻辑了。 What is the right syntax to achieve it?
实现它的正确语法是什么?
A couple of tips here: 这里有几个提示:
"#{}"
operator. "#{}"
运算符将变量连接到查询中是一种危险的做法。 Doing so bypasses query parameterization and could leave your app open to SQL injection . "?"
"?"
in your where clause. With these two things in mind, I would start by refactoring your query like so: 考虑到这两点,我将以如下方式重构您的查询开始:
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)
You will note that I replaced 18.months
with 46656000
. 您会注意到,我用
18.months
替换了46656000
。 This saves a few clock cycles in the Rails app. 这样可以在Rails应用程序中节省几个时钟周期。 Depending on your database schema, the last where clause may not work.
根据您的数据库架构,最后的where子句可能不起作用。 The modification below may end up working better.
下面的修改可能会更好地工作。
As a further refinement, you could refactor your last where clause to look for a release date that is between 18 months before @mobile.release_date
and 18 months after. 作为进一步改进,您可以重构您的last where子句以查找发布日期,该发布日期在
@mobile.release_date
之前的18个月与之后的18个月之间。 The saves your MySql database from having to do the math on each record and may lead to better performance: 这样就不必对每条记录进行数学运算,从而节省了MySql数据库的时间,并且可能导致更好的性能:
.where(release_date: (@mobile.release_date - 18.months)..(@mobile.release_date + 18.months) )
I do not know your database schema, so you may run into date conversion problems with the code above. 我不知道您的数据库架构,因此您可能会遇到上述代码的日期转换问题。 I recommend you play with it in the Rails console.
我建议您在Rails控制台中使用它。
Use a Range to query between dates/times: 使用范围查询日期/时间之间:
Mobile.where("price >= ?", @mobile.price)
.where.not(id: @mobile.id)
.where(release_date: 18.months.ago..Time.now)
.order(price: :ASC)
.first(4)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.