2017-11-21 11 views
1

ミリ秒で書式設定された日付を含むBIGINTがあります。私は、選択された列の年ごとにレコードをフィルタリングするために探していますcreated_at。私はデータベースとしてMYSQLを使用しています。ミリ秒変換して年を取得

これはこれまでのコントローラでこれまでのことです。

次のエラーを提供
@agent = Agent.where('Time.at(created_at/1000).year = ?', '2017') 

:あなたがそう知っている限り

Mysql2::Error: You have an error in your SQL syntax 

答えて

2

データベースは、あなたがそのようなwhereコール、SQLのスニペット、ないルビーwhere作品の形でそれを使用することはできませんのでTime.at(created_at/1000).yearのようなRubyのコードを理解していません。

"エポックからのミリ秒" created_at値から年を抽出する作業をデータベースに実行させることができます。あなたはワンステップで適切な形式の文字列を使用してMySQLのfrom_unixtime機能を使用していることを行うことができます。ほとんどのデータベースにRubyのコードを送信するようにしようと同じ読み

Agent.where("from_unixtime(created_at/1000, '%Y') = ?", '2017') 

を。

もちろん、Rubyでの作業は、Charlie Weems's answerのように行うことができます。

これをたくさんしていて、見ている行の数を減らすためにWHERE節に他に何もない場合は、各アプローチがどのようなインデックスと相互作用するかを比較することをお勧めします。

+1

両方の答えは実線です。しかし、この方法は私のニーズをより良く適合させます。助けを感謝します! – DollarChills

2

、私はあなたがそのような場所の比較のTime.at内部を行うことができるとは思いません。

一つのアプローチは、比較を逆転、そしてエポックからのミリ秒に年間有効にするようになります:

comparison_time = (Time.new(2017, 1, 1).to_f * 1000).to_i 
@agent = Agent.where("created_at = ?", comparison_time) 

注:あなたの行が年に正確にタイムスタンプされている場合は、あなたが使用できるような比較に等しいですあなたの例では。それ以外の場合は、開始日と終了日の両方が必要になるため、範囲を返すことができます。例:

start_time = (Time.new(2017, 1, 1).to_f * 1000).to_i 
end_time = (Time.new(2018, 1, 1).to_f * 1000).to_i 
@agent = Agent.where("created_at >= ? AND created_at <= ?", start_time, end_time) 

別のアプローチは、あなたが大きなテーブルを持っている場合、これは大量のメモリを取ることができる、DateTimeにそれぞれのcreated_atとを変換し、しかし、2017年に比較して、あなたの薬のすべてをループになりますRailsはMySQLとは対照的に操作を行うためです。

関連する問題