【问题标题】:Rails: showing data in a crosstabRails:在交叉表中显示数据
【发布时间】:2016-12-06 04:07:41
【问题描述】:

我正在制作支出日记,因此在我看来需要一个交叉表。该应用程序有一个支出表。该表中的每条记录都是单个支出,其中包含(除其他外)“Value”(作为整数)、“Day”(作为日期)和“Category_ID”(作为整数和外键)。

我想要做的是显示一个表格,显示用户每个月在每个类别上花费了多少。

因此我需要做两件事:

  1. 按月份和类别对所有支出进行分组
  2. 在视图中显示

换句话说,我想从:

收件人:

我怎样才能做到这一点?一直在寻找,但没有找到合适的解决方案。

此外,我想显示的不是“Category_ID”而是类别的名称(来自类别连接表)。

更新: 到目前为止,我尝试了以下方法:

@expenditures = Expenditure.where(:user_id => current_user)
@grouped_exp = @expenditures.includes(:category).group("DATE_TRUNC('month', day)", :name).sum(:value)

现在给了我:

[[[2016-08-01 00:00:00 UTC, "housing | electricity"], -31.0], [[2016-09-01 00:00:00 UTC, "other | pharmacy & drugstore"], -9.5], [[2016-08-01 00:00:00 UTC, "financials | salary"], 2913.92], [[2016-10-01 00:00:00 UTC, "housing | internet"], -26.06], ... ]

所以我现在每个月都有每个类别的总和。但是,我不知道这是否是正确的方法,如果是,下一步将是什么。

【问题讨论】:

  • 我在帖子中添加了更新。

标签: ruby-on-rails postgresql crosstab


【解决方案1】:

您要创建的表不能这样完成。它似乎有对应于一年中几个月的动态列。这不能使用 ActiveRecord 完成。您必须直接使用 SQL 并以编程方式生成查询,始终选择每列的特定日期范围。除非您是 SQL 英雄,否则这可能不是一个好主意。

你需要的是更像这样的东西

Category.joins(:expenditures).
  where("expenditures.user_id = ?", current_user).
  group("categories.id, DATE_TRUNC('month', day)").
  select("categories.name, DATE_TRUNC('month', day) AS month, SUM(value) AS sum")

这会给你类似的记录

r = records.first
r.name => 'Some category'
r.month => '2016-10'
r.sum => 55

【讨论】:

    【解决方案2】:

    你可以试试这样的:

    @expenditures
      .joins(:category)
      .select('DATE_TRUNC('month', day) as day, category_id, sum(value) as total')
      .group('day, category_id, total')
    

    【讨论】:

    • 好的,试过了。如果我在我看来 我得到:#<:activerecord_relation:0x007fe9fc55ab48>
    • 如果我这样做 我得到:PG::GroupingError: ERROR: column "expenditures.category_id" 必须出现在 GROUP BY 子句中或在聚合函数中使用第 1 行:选择 DATE_TRUNC('month', day) as day, category_id, sum(val...
    • 那么查询有问题,在控制台中运行它并尝试获取第一个值。您将看到执行的 SQL 查询以及错误
    • 将其他字段添加到组语句中。可以再试一次吗?
    • 我在控制台中运行了您的第一个提案:ActiveRecord::StatementInvalid: PG::GroupingError: ERROR: column "expenditures.category_id" 必须出现在 GROUP BY 子句中或用于聚合函数 LINE 1: SELECT DATE_TRUNC('month', day) as day, category_id, sum(val... ^ : SELECT DATE_TRUNC('month', day) as day, category_id, sum(value) FROM "expenditures" INNER JOIN "categories " ON "categories"."id" = "expenditures"."category_id" GROUP BY "expenditures"."day"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多