【问题标题】:Generating JSON response with PostgreSQL for Rails使用 PostgreSQL for Rails 生成 JSON 响应
【发布时间】:2016-06-21 17:37:15
【问题描述】:

我目前正在 Rails 中执行一条 SQL 语句,虽然它有效,但我开始意识到我需要一种不同的格式,并试图在 PostreSQL 中完成它。这是我的查询:

    sql = "SELECT one_month_high - one_month_low as one_month,
          three_month_high - three_month_low as three_month,
          six_month_high - six_month_low as six_month,
          twelve_month_high - twelve_month_low as twelve_month,
          ytd_high - ytd_low as ytd,
          saved_on
          FROM daily_high_lows
          ORDER BY saved_on DESC;"

返回:

#<PG::Result:0x007fdb4aea1fa0 status=PGRES_TUPLES_OK ntuples=380 nfields=6 cmd_tuples=380>
...
{"one_month"=>"544", "three_month"=>"214", "six_month"=>"9","twelve_month"=>"122",
"ytd"=>"143", "saved_on"=>"2016-06-09 00:00:00"}
{"one_month"=>"1283", "three_month"=>"475", "six_month"=>"22","twelve_month"=>"189",
"ytd"=>"517", "saved_on"=>"2016-06-08 00:00:00"}

我意识到我需要一种格式:

[
  {
    name: "One Month",
    data: {
      2016-06-09 00:00:00: 544,
      2016-06-08 00:00:00: 1283
    }
  },
  {
    name: "Three Month",
    data: {
     2016-06-09 00:00:00: 214,
     2016-06-08 00:00:00: 475
    }
  }, etc...
] 

我一直在尝试研究如何做到这一点,但目前它有点超出我的能力,所以我可以使用一些方向。

【问题讨论】:

    标签: ruby-on-rails json postgresql


    【解决方案1】:

    您应该能够使用 rails 中提供的 to_json 方法。所以response.to_json 应该能满足你的需要。

    【讨论】:

    • 这对于我的特殊情况来说可能有点过头了,但我正在寻找类似的东西:PG JSON for Rails。使用 to_json 只会以 json 格式返回原始结果,我仍然需要将其操作为所需的格式。
    【解决方案2】:

    我认为,如果您有很多记录,在 Postgres 中构建 JSON 是一种很好的方法。 Postgres 直到 9.4 才真正获得非常有用的 JSON 构建功能,所以我建议你至少在那里,如果不是更高的话。无论如何,这似乎给了你想要的:

    WITH seqs AS (
      SELECT  json_object_agg(saved_on::text, one_month_high ORDER BY saved_on) one_month_highs,
              json_object_agg(saved_on::text, one_month_low ORDER BY saved_on) one_month_lows
      FROM    daily_high_lows
    )
    SELECT  json_agg(j)
    FROM    (
      SELECT json_build_object('name', 'One Month Highs', 'data', one_month_highs)
      FROM   seqs
      UNION ALL
      SELECT json_build_object('name', 'One Month Lows', 'data', one_month_lows)
      FROM seqs
    ) x(j)
    ;
    

    测试如下:

    t=# create table daily_high_lows (one_month_high integer, one_month_low integer, three_month_high integer, three_month_low integer, six_month_high integer, six_month_low integer, twleve_month_high integer, twelve_month_low integer, ytd_high integer, ytd_low integer, saved_on timestamp);
    t=# insert into daily_high_lows (one_month_high, one_month_low, three_month_high, three_month_low, saved_on) values (1, 10, 3, 6, '2016-06-08');
    t=# insert into daily_high_lows (one_month_high, one_month_low, three_month_high, three_month_low, saved_on) values (2, 9, 3, 8, '2016-03-09');
    t=# with seqs as (select json_object_agg(saved_on::text, one_month_high order by saved_on) one_month_highs, json_object_agg(saved_on::text, one_month_low order by saved_on) one_month_lows from daily_high_lows) select json_agg(j) from (select json_build_object('name', 'One Month Highs', 'data', one_month_highs) from seqs union all select json_build_object('name', 'One Month Lows', 'data', one_month_lows) from seqs) x(j);
                                                                                                  json_agg                                                                                              
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     [{"name" : "One Month Highs", "data" : { "2016-03-09 00:00:00" : 2, "2016-06-08 00:00:00" : 1 }}, {"name" : "One Month Lows", "data" : { "2016-03-09 00:00:00" : 9, "2016-06-08 00:00:00" : 10 }}]
    (1 row)
    

    【讨论】:

    • 感谢您提供信息丰富的回复。不幸的是,我目前的情况并没有解决,所以我需要进一步调查,但这是一个非常宝贵的 sn-p,我相信它会帮助我。
    猜你喜欢
    • 2018-03-10
    • 2020-05-15
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多