2016-05-15 57 views
2

之間的天差數這是我的SQL查詢:結合Ruby的變量在SQL語句中軌找到兩個日期

Battle.all.order("votes_count/#{(DateTime.now.to_i - created_at.to_i)/86400}") 

votes_countcreated_at是戰列;我想通過DateTimenowbattlecreated_at天差異來劃分votes_count。 現在我得到一個語法錯誤;我怎麼能使它工作?我在我的Rails 4應用程序中使用PostgreSQL。

編輯

改爲「以「

的錯誤,我得到:

NameError: undefined local variable or method 'created_at' for main:Object 

created_at是戰列不是紅寶石變量..

感謝

+0

請正確嵌套您的引號{},()。 – Meier

+0

謝謝,更新我的代碼 – gal

回答

2

第一個錯誤是th在你的字符串插值沒有得到應用,因​​爲你使用了一個單引號字符串。您需要使用雙引號字符串才能使字符串插值正確工作。

試試這個,而是:

Battle.all.order("votes_count/#{(DateTime.now.to_i - created_at.to_i)/86400}") 

這將使插值正常工作,但會導致你遇到的第二個錯誤,在處理插值發生。

第二錯誤是由試圖使用的created_at值中內插,在運行SQL之前發生而引起的。取而代之的是,重構該查詢使用這種形式:

Battle.all.order("votes_count/('#{DateTime.now}' - created_at)/86400") 

在該代碼中,僅DateTime.now值被包括在插值中,括號已被移動的內插值外,和#{DateTime.now}結果包圍單引號使結果值對SQL友好。 to_i已從兩個表達式中刪除,以允許在SQL中完成日期減法。

注意,應謹慎使用SQL日期時間減法被使用,如日期時間減法的語法不同於一個數據庫產品廣泛到另一個一樣,減法運算的結果。在一些常見的數據庫中減去日期時間值的

例子:

| Database | Syntax            | Result Units | 
|-----------|-------------------------------------------------------|--------------| 
| Postgres | datetime1 - datetime2         | Interval  | 
| MySQL  | TIMEDIFF(datetime1, datetime1)      | Seconds  | 
| SQLServer | DATEDIFF(second, datetime1, datetime2)    | Seconds  | 
| DB2  | SECOND(datetime1,s) - SECOND(datetime2,s)    | Seconds  | 
| SQLite | strftime('%s', datetime1) - strftime('%s', datetime2) | Seconds  | 
+0

替換'與「 - 仍然不工作 – gal

+0

我在rails控制檯中測試這個SQL查詢。它應該在那裏工作 – gal

+0

SQL查詢有語法錯誤,它不會運行 – gal

2

這應該解決您的問題:

to_date_str = "to_date('#{DateTime.now.strftime '%d/%m/%Y %H:%M'}', 'DD/MM/YYYY HH24:MI')" 

str = "votes_count/(EXTRACT(epoch FROM (#{to_date_str} - created_at))/86400)::int" 

Battle.order(str) 

你有第一個問題是一個語法錯誤。

您的語法錯誤是由於您使用單引號'而不是雙引號"

使用單引號時,表達式#{(DateTime.now.to_i - created_at.to_i)/86400}不會被其值替換,而使用雙引號將被計算並插入到字符串中。

所以要解決你的語法錯誤使用:

Battle.all.order("votes_count/#{(DateTime.now.to_i - created_at.to_i)/86400}") 

但它並沒有完全解決你的問題。你有NameError: undefined local variable or method 'created_at' for main:Object。爲什麼?

你得到了這個錯誤,因爲你正在計算字符串"votes_count/#{(DateTime.now.to_i - created_at.to_i)/86400}"之前order得到執行。所以在這一點上,紅寶石不知道正在處理哪個戰鬥。實際上它並不知道,因爲此時沒有進行任何戰鬥。這就是爲什麼紅寶石告訴你沒有「created_at」。解決方案是使用SQL,而不是試圖在ruby中完成它。

+0

替換爲「with」 - 仍然不起作用 – gal

+0

我認爲這是不公平的。即使這不是完整的解決方案,這也是解決方案的第一步。答案的作者不是錯誤的海報已經犯了幾個錯誤,以便修復其中一個錯誤是不夠的。 – Meier

+0

@gal你可以嘗試我現在​​應該工作的新解決方案。 – Pholochtairze