Rails+PostgreSQL: EXTRACT関数で期間をスマートに扱う(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

Rails+PostgreSQL: EXTRACT関数で日付をスマートに扱う方法(翻訳)

eコマースプラットフォームを実装中に、今年の注文をすべて取り出したくなったとしましょう。Railsでこれをやれる最もシンプルな方法はどんなものがあるでしょうか。おそらく次のようなクエリを書くのではないでしょうか。

Order.where("created_at >= ? AND created_at < ?", 
Date.today.beginning_of_year, 
Date.today.beginning_of_year.next_year)

これでもやれますが、どうにも不自然な方法で範囲フィルタする必要があります。何らかのネイティブ関数を用いて、一般的なユースケースに耐えうる方法で扱うべきでしょう。しかしそんなことが可能なのでしょうか?

実はあるのです。EXTRACT関数とnow()関数を使います。前者はタイムスタンプから現在のを抽出でき、後者は現在時刻を取り出せます。

2つの関数を組み合わせれば、次のようなクエリを書けます。

Order.where("EXTRACT(year FROM created_at) = EXTRACT(year FROM now())")

断然スッキリしました!この方法のようにEXTRACT(year FROM created_at)の関数的インデックスを作成すれは、シーケンシャルスキャンを回避してパフォーマンスを著しく高めることもできます。

関連記事

Rails: データベーススキーマをダウンタイムなしで変更する(翻訳)

データベースのランダム読み出しは要注意(翻訳)

Rails: データベースのパフォーマンスを損なう3つの書き方(翻訳)

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ