ruby-on-rails - Arel:从函数中选择

标签 ruby-on-rails ruby arel

考虑以下查询:

SELECT DATE_TRUNC('hour', date_range) 
FROM GENERATE_SERIES(:start_date, :end_date, :interval) as date_range

是否可以将 GENERATE_SERIES(...) 用作表(数据源)?理想情况下,它看起来像这样:

t = series(start, end, as: 'date_range')
dt = Arel::Nodes::NamedFunction.new('DATE_TRUNC', ['hour', t[:date_range]])
t.project(dt)

更新 1。为什么我需要 GENERATE_SERIES?我有一些数据需要处理,这些数据与此数据可用的时间戳有关,并将其输出为二维图。作为一个简单的例子,考虑一个 clickstream = (id, created_at)。我想针对给定的日期时间网格(即 Nov 17、Nov 18、Nov 19、...、Nov 30)绘制在特定日期之前进行的点击次数。关键是我希望这一切都发生在 PostgreSQL 中。

Upd2。没有变量的示例查询可能如下所示:

SELECT DATE_TRUNC('hour', date_range) FROM GENERATE_SERIES('2015-01-01 00:15:38'::TIMESTAMP, '2015-01-10 23:59:59'::TIMESTAMP, '1 HOUR') as date_range;

最佳答案

一种方法是简单地手动构建 AST 的所有必要部分

def timestamp(ts)
  Arel::Nodes::NamedFunction.new(
    'CAST', [
      Arel::Nodes::As.new(
        Arel::Nodes.build_quoted(ts),
        Arel::Nodes::SqlLiteral.new('timestamp')
      )
    ]
  )
end

def series(from, to, by, options = {})
  Arel::Nodes::NamedFunction.new(
    'GENERATE_SERIES', [
      timestamp(from),
      timestamp(to),
      Arel::Nodes::SqlLiteral.new(by)
    ]
  ).as(options.fetch(:as, 'series'))
end

def date_trunc(by, attribute)
  Arel::Nodes::NamedFunction.new(
    'DATE_TRUNC', [Arel.sql("'#{by}'"), attribute]
  )
end

date_range = Arel::Table.new('date_range')
result = date_range.
  from(series(5.days.ago, 4.days.ago, "'1 hour'", as: 'date_range')).
  project(date_trunc('hour', date_range[:date_range]))

测试:

User.find_by_sql(result.to_sql).to_a.map &:attributes    

SELECT DATE_TRUNC('hour', "date_range"."date_range")
FROM GENERATE_SERIES(
  CAST('2015-02-03 21:29:22.729188' AS timestamp),
  CAST('2015-02-04 21:29:22.729633' AS timestamp),
  '1 hour'
) AS date_range

[{"date_trunc"=>2015-02-03 21:00:00 UTC, "id"=>nil},
 {"date_trunc"=>2015-02-03 22:00:00 UTC, "id"=>nil},
 {"date_trunc"=>2015-02-03 23:00:00 UTC, "id"=>nil},
 {"date_trunc"=>2015-02-04 00:00:00 UTC, "id"=>nil},
# ...
 {"date_trunc"=>2015-02-04 21:00:00 UTC, "id"=>nil}]

关于ruby-on-rails - Arel:从函数中选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27359473/

相关文章:

ruby-on-rails - accepts_nested_attributes_for 验证和使用 find_or_create_by

ruby-on-rails - 测试是否缺少输入标签的值属性

ruby-on-rails - 使用 Rails、Paperclip 和 Backbone 上传文件

ruby - 使用 Middleman 在 Markdown 中渲染 ERb 模板的部分

ruby-on-rails - Rails ORM 是否限制执行聚合的能力?

ruby-on-rails - 在 Rails 2.2.2 中动态地向 ActiveRecord 模型添加字段?

ruby-on-rails - Rails 3.2.15 迁移失败 : undefined method `create_join_table'

sql - "x IS NULL"和 "NOT (x IS NOT NULL)"有什么区别?

ruby-on-rails - 使用 Rails 查询语言进行复杂查询

ruby-on-rails - 我如何编写最有效的范围来仅询问那些具有某些子对象的父对象