2011-04-04 51 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