使用原始SQL查询返回ActiveRecord :: Relation

时间:2019-03-27 12:27:04

标签: ruby-on-rails

下面是indicator_values数据库表的几行,其中包含国家和重复年份的指标的记录:

enter image description here

我希望将与每个国家最近的年份对应的value放入数组:

[{"name"=>"Water", "data"=>[86.35, 88.34]},                #indicator2
 {"name"=>"Electricity", "data"=>[68.62, 94.47]}, ....]    #indicator1

我可以使用查询获取每个国家和指标的最近几年数据,然后对SQL查询返回的对象应用.where().pluck()有效记录查询。

[2,3,4].map { |i| 
        sql = "SELECT a.country_id,  a.indicator_id, a.value, a.year
              FROM indicator_values a
              INNER JOIN (
                SELECT country_id, indicator_id, MAX(year) AS year
                FROM indicator_values
                GROUP BY country_id, indicator_id
              ) b ON a.country_id = b.country_id AND a.year = b.year and a.indicator_id = b.indicator_id
              ORDER BY country_id, indicator_id;"

        recent_years_data = ActiveRecord::Base.connection.execute(sql)
        my_array = { "name" => Indicator.find(i).name, "data" => recent_years_data.where('indicator_id = (?) and country_id IN (?)', i, selected_countries).pluck(:value) } }

查询的结果不是ActiveRecord::Relation对象,因此不能与.where().pluck()一起使用。我寻求一种方法来获得ActiveRecord::Relation或其他解决方法来创建所需的数组。类似的帖子提出了使用Active Record Query的建议,但是我不知道如何将这样长的查询链接为Active Record Query而不是原始SQL。

1 个答案:

答案 0 :(得分:0)

我得到了一种有效的方法,该方法不涉及使用联接。

IndicatorValue.
    select('DISTINCT ON (cvs.country_id, cvs.indicator_id), cvs.*').
    order('cvs.country_id, cvs.indicator_id, cvs.year DESC') 

cvs代表indicator_values 结果是ActiveRecord::Relation