[英]rails difference between two dates inside .where
這是我的邏輯,我想將最昂貴的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)
第一個.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注入 。 而是使用"?"
在您的where子句中。 考慮到這兩點,我將以如下方式重構您的查詢開始:
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子句可能不起作用。 下面的修改可能會更好地工作。
作為進一步改進,您可以重構您的last where子句以查找發布日期,該發布日期在@mobile.release_date
之前的18個月與之后的18個月之間。 這樣就不必對每條記錄進行數學運算,從而節省了MySql數據庫的時間,並且可能導致更好的性能:
.where(release_date: (@mobile.release_date - 18.months)..(@mobile.release_date + 18.months) )
我不知道您的數據庫架構,因此您可能會遇到上述代碼的日期轉換問題。 我建議您在Rails控制台中使用它。
使用范圍查詢日期/時間之間:
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.