当我运行此查询时......
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'
我尝试更改引号和反引号,但没有运气。
答案 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>]>