=-6ren">
gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 04:34:30 25 4
gpt4 key购买 nike

这是我的逻辑我想获得最接近特定手机 @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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com