PG :: SyntaxError:带有to_date的Rails where子句中的ERROR

时间:2017-10-16 19:46:50

标签: ruby-on-rails postgresql

当我运行此查询时......

OnlineCourseRegistration.where("exam_completed_at.strftime('%m/%d/%Y').to_date + 360 = ?", Date.today)

我收到此错误...

2.3.0 :012 >   OnlineCourseRegistration.where("exam_completed_at.strftime('%m/%d/%Y').to_date = ?", Date.today)
  OnlineCourseRegistration Load (0.5ms)  SELECT "class_registrations".* FROM "class_registrations" INNER JOIN "course_classes" ON "course_classes"."id" = "class_registrations"."course_class_id" INNER JOIN "courses" ON "courses"."id" = "course_classes"."course_id" INNER JOIN "users" ON "users"."id" = "class_registrations"."user_id" WHERE (course_classes.class_type = 'online') AND (exam_completed_at.strftime('%m/%d/%Y').to_date = '2017-10-16')
PG::SyntaxError: ERROR:  syntax error at or near "."
LINE 1: ...line') AND (exam_completed_at.strftime('%m/%d/%Y').to_date =...
                                                             ^
: SELECT "class_registrations".* FROM "class_registrations" INNER JOIN "course_classes" ON "course_classes"."id" = "class_registrations"."course_class_id" INNER JOIN "courses" ON "courses"."id" = "course_classes"."course_id" INNER JOIN "users" ON "users"."id" = "class_registrations"."user_id" WHERE (course_classes.class_type = 'online') AND (exam_completed_at.strftime('%m/%d/%Y').to_date = '2017-10-16')
ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR:  syntax error at or near "."
LINE 1: ...line') AND (exam_completed_at.strftime('%m/%d/%Y').to_date =...
                                                             ^
: SELECT "class_registrations".* FROM "class_registrations" INNER JOIN "course_classes" ON "course_classes"."id" = "class_registrations"."course_class_id" INNER JOIN "courses" ON "courses"."id" = "course_classes"."course_id" INNER JOIN "users" ON "users"."id" = "class_registrations"."user_id" WHERE (course_classes.class_type = 'online') AND (exam_completed_at.strftime('%m/%d/%Y').to_date = '2017-10-16')
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/connection_adapters/postgresql_adapter.rb:774:in `async_exec'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/connection_adapters/postgresql_adapter.rb:774:in `exec_no_cache'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:138:in `block in exec_query'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/connection_adapters/abstract_adapter.rb:435:in `block in log'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activesupport-4.0.2/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/connection_adapters/abstract_adapter.rb:430:in `log'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:137:in `exec_query'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/connection_adapters/postgresql_adapter.rb:891:in `select'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/connection_adapters/abstract/database_statements.rb:24:in `select_all'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/connection_adapters/abstract/query_cache.rb:63:in `select_all'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/querying.rb:36:in `find_by_sql'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/relation.rb:585:in `exec_queries'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/relation.rb:471:in `load'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/relation.rb:220:in `to_a'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/relation.rb:598:in `exec_queries'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/relation.rb:471:in `load'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/relation.rb:220:in `to_a'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/activerecord-4.0.2/lib/active_record/relation.rb:573:in `inspect'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/railties-4.0.2/lib/rails/commands/console.rb:90:in `start'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/railties-4.0.2/lib/rails/commands/console.rb:9:in `start'
    from /Users/marklocklear/.rvm/gems/ruby-2.3.0/gems/railties-4.0.2/lib/rails/commands.rb:62:in `<top (required)>'
    from bin/rails:4:in `require'

我尝试更改引号和反引号,但没有运气。

4 个答案:

答案 0 :(得分:1)

postgresql中,您有to_char函数将日期转换为字符串。

to_char(timestamp, text)

但是您需要时间戳类型,因此您需要使用current_timestamp

因此,要获得360天前的时间戳,请使用:

current_timestamp - interval '360 days'

获取具有该日期的字符串:

<强> SQL DEMO

to_char(current_timestamp - interval '360 days', 'MM/dd/YYYY')

这会生成一个常量值,因此可以与索引一起使用。

所以你的ruby代码应该是:

.where("exam_completed_at = to_char(current_timestamp - interval '360 days', 'MM/dd/YYYY')

答案 1 :(得分:0)

你将SQL和ruby混为一谈。

exam_completed_at.strftime('%m/%d/%Y').to_date是Ruby代码,但您可以在SQL中运行它。

修复和使用更漂亮的AREL(假设exam_completed_at是要过滤的数据库字段而不是局部变量)的一种方法是使用日期范围:

where(
  exam_completed_at: 
    (Date.today.beginning_of_day - 360.days)..(Date.today.end_of_day - 360.days)
)

答案 2 :(得分:0)

试试这个:

OnlineCourseRegistration.where("(created_at - current_timestamp) < interval '360 day'")

答案 3 :(得分:0)

经过大量捕鲸和咬牙切齿之后,我认为我有我正在寻找的查询。我还在测试,但到目前为止似乎有效。

只是为我试图运行的原始查询添加一些上下文。用简单的英语,我试图找到exam_completed_at日期是今天日期之前一年的记录。另一种方式我正在寻找记录,其中exam_completed_at日期是今天的日期减去360(或一年)。

以下是我提出的建议:

OnlineCourseRegistration.where("exam_completed_at BETWEEN ? AND ?", DateTime.now.beginning_of_day - 1.year, DateTime.now.end_of_day - 1.year)

作为完整性检查,请查看此记录:

  2.3.0 :276 > OnlineCourseRegistration.find 14340
D, [2017-10-17T10:01:54.622455 #35257] DEBUG -- :   OnlineCourseRegistration Load (0.9ms)  SELECT "class_registrations".* FROM "class_registrations" INNER JOIN "course_classes" ON "course_classes"."id" = "class_registrations"."course_class_id" INNER JOIN "courses" ON "courses"."id" = "course_classes"."course_id" INNER JOIN "users" ON "users"."id" = "class_registrations"."user_id" WHERE (course_classes.class_type = 'online') AND "class_registrations"."id" = $1 LIMIT 1  [["id", 14340]]
 => #<OnlineCourseRegistration id: 14340, cart_id: 15093, user_id: 7090, course_class_id: 681, created_at: "2017-09-05 15:19:23", updated_at: "2017-10-17 13:29:08", exam_attempts: 0, exam_completed_at: "2016-10-17 13:29:03", evaluation_completed_at: nil, status: "Active", score: nil, add_extension: false, retest_cart_id: nil, retest_purchased_at: nil>

...并注意exam_completed_at日期为2016-10-17 13:29:03。现在当我运行查询时,我得到了相同的记录:

2.3.0 :275 >  OnlineCourseRegistration.where("exam_completed_at BETWEEN ? AND ?", DateTime.now.beginning_of_day - 1.year, DateTime.now.end_of_day - 1.year)
D, [2017-10-17T09:59:27.832326 #35257] DEBUG -- :   OnlineCourseRegistration Load (2.2ms)  SELECT "class_registrations".* FROM "class_registrations" INNER JOIN "course_classes" ON "course_classes"."id" = "class_registrations"."course_class_id" INNER JOIN "courses" ON "courses"."id" = "course_classes"."course_id" INNER JOIN "users" ON "users"."id" = "class_registrations"."user_id" WHERE (course_classes.class_type = 'online') AND (exam_completed_at BETWEEN '2016-10-17 04:00:00.000000' AND '2016-10-18 03:59:59.000000')
 => #<ActiveRecord::Relation [#<OnlineCourseRegistration id: 14340, cart_id: 15093, user_id: 7090, course_class_id: 681, created_at: "2017-09-05 15:19:23", updated_at: "2017-10-17 13:29:08", exam_attempts: 0, exam_completed_at: "2016-10-17 13:29:03", evaluation_completed_at: nil, status: "Active", score: nil, add_extension: false, retest_cart_id: nil, retest_purchased_at: nil>, #<OnlineCourseRegistration id: 14267, cart_id: 15004, user_id: 7069, course_class_id: 681, created_at: "2017-07-15 22:06:06", updated_at: "2017-10-17 13:49:17", exam_attempts: 1, exam_completed_at: "2016-10-17 13:49:11", evaluation_completed_at: "2017-07-20 23:59:01", status: "Completed", score: "87", add_extension: false, retest_cart_id: nil, retest_purchased_at: nil>]>