2011-04-04 72 views
0

我得到這個錯誤:如何在PGSQL中按日期搜索?

ActionView :: Template :: Error(PGError:ERROR:運算符不存在:timestamp沒有時區~~未知LINE 1:...「articles」WHERE(「articles」 「created_at」LIKE'2010 ...

我有一個存檔控制器,我可以動態顯示文章的類型和年份,月份和日期,無論那些字段在URL中可用。這個指數的行動:

def index 
    filter_title 
    @articles = Article.where(:created_at.matches % date_builder, :genre.matches % genre_builder).order("created_at DESC") 
    respond_to do |format| 
    format.json { render :json => @articles } 
    format.xml { render :xml => @articles } 
    format.html 
    end 
end 

這date_builder功能

def date_builder 
    @date = "" 
    @date += params[:year] if !(params[:year].nil?) 
    @date += "-" + params[:month] if !(params[:month].nil?) 
    @date += "-" + params[:day] if !(params[:day].nil?) 
    @date += "%" 
    @date 
end 

將使用metawhere來查找匹配我提供的字符串部分的日期。這在Sqlite中完美運行。我已將我的應用程序遷移到heroku和PGSQL,並且不允許我這樣做。解決辦法是什麼?謝謝!

回答

1

Postgres裏,時間戳不存儲爲一個字符串像sqllite:

select 'A' where localtimestamp like '2011-04-04%'; 
ERROR: operator does not exist: timestamp without time zone ~~ unknown 

有關使用>=,而不是如何?

select 'A' where localtimestamp >= '2011-04-04'; 

?column? 
---------- 
A 
(1 row) 
+0

@Leon是 - 或'選擇 'A',其中date_trunc( '年',LOCALTIMESTAMP)= '2011-01-01';'或'選擇 'A',其中TO_CHAR(LOCALTIMESTAMP,「YYYY ')='2011';'如果你更喜歡 – 2011-04-04 17:17:01

+0

所以如果它只是一年做 選擇 'A',其中created_at> = '2011-01-01' AND created_at < '2012-01-01' 和年份和月份 選擇 'A',其中created_at> =「2011-01- 01'AND created_at <'2011-02-01' 等? – illogikal 2011-04-04 17:27:35

+0

是的。這意味着可以使用'created_at'上的索引,如果轉換爲字符串,通常情況下不會這樣。 – araqnid 2011-04-04 18:23:51

0

雖然喜歡在那裏@JackPDouglas回答,我想盡量保持SQL代碼我的項目,儘可能,所以我落得這樣做的:

... 
date_builder 
    if !(params[:year].nil?) 
    @articles = Article.where(
     {:created_at.gt => @datelower} & 
     {:created_at.lt => (@datehigher - 1.second)} & 
     :genre.matches % genre_builder 
    ).order("created_at DESC") 
    else 
... 

這種方法爲日期:

def date_builder 
    if !(params[:day].nil?) 
    @datelower = Time.utc(params[:year], params[:month], params[:day]) 
    @datehigher = @datelower + 1.day 
    elsif !(params[:month].nil?) 
    @datelower = Time.utc(params[:year], params[:month], 01) 
    @datehigher = @datelower + 1.month 
    elsif !(params[:year].nil?) 
    @datelower = Time.utc(params[:year], 01, 01) 
    @datehigher = @datelower + 1.year 
    end 
end 
+0

我對Hibernate不太瞭解,但是不會'{:created_at.ge => @datelower}&{:created_at.lt => @datehigher}'變得更好嗎?否則,我認爲你會錯過一些比賽。 – 2011-04-05 13:12:02