需要帮助在Rails中编写SQL查询,所以我得到了ActiveRelation

时间:2019-06-21 18:18:08

标签: ruby-on-rails activerecord

我需要一个主动的记录关系,该关系可以为我提供有关地区,城市,床位组合的最新记录。我有如下编写的sql查询,但是我需要弄清楚是否可以使用其他方法来使它返回活动记录关系而不是数组。有什么建议吗?

当前查询:

    @current_ltm_market_stats = LtmStatsByBedCount.find_by_sql(" SELECT *
          FROM ltm_stats_by_bed_counts lstats
          WHERE lstats.city_id = '#{@city_id}'
              #{@region_id_condition}
              AND (lstats.beds,lstats.city_id,lstats.region_id,lstats.reporting_date) 
            IN (SELECT lstats.beds,
                  lstats.city_id,
                  lstats.region_id,
                  max(lstats.reporting_date)
                                                          FROM ltm_stats_by_bed_counts lstats 
        WHERE lstats.city_id = '#{@city_id}'
         #{@region_id_condition}
         GROUP BY city_id, region_id, beds)
          ORDER BY lstats.year DESC,lstats.month DESC")

我曾经尝试过这样做,但是确实导致了关联,但是它运行得很慢,结果也不完全相同。有没有更好的方法可以做到这一点?

@all_ltm_market_stats = LtmStatsByBedCount.where(city_id: @market.city_id, region_id: @market.region_id)
        @current_ltm_market_stats = @latest_year_ltm_market_stats.where(month: @latest_year_ltm_market_stats.all_ltm_market_stats.select('Max(year)'))

1 个答案:

答案 0 :(得分:0)

该问题的信息不完整,因此当添加其他详细信息时我可能不得不更新我的答案
但这是具有可用信息的初始草案:

@current_ltm_market_stats = LtmStatsByBedCount.
  where(city_id: @city_id).
  where(@region_id_condition).
  where("(beds, city_id, region_id, reporting_date) IN (
    SELECT lstats.beds,
           lstats.city_id,
           lstats.region_id,
           max(lstats.reporting_date)
           FROM ltm_stats_by_bed_counts lstats 
           WHERE lstats.city_id = '#{@city_id}'
           #{@region_id_condition}
           GROUP BY city_id, region_id, beds)").
  order(year: :desc, month: :desc)

请注意,您可能需要稍微调整 @region_id_condition 才能使其正常工作。

理论上它等效于您的SQL版本(这意味着它将生成相同的sql(不包括表别名)并返回AR关系对象。这是问题中的唯一要求。显然,SQL可能还会通过附加信息得到改进。

此外,如果要在较大的数据集上频繁使用此查询,则希望在此表上精心设计索引。