2

2 つのテーブルがchartsありchart_entries、現在の上位 5 つのチャート位置を取得したいと考えています (chart_entries特定の位置で最新のものを選択することに基づいて)。

これを単一のクエリにする方法はありますか? 理想的には、私のチャートには最大 500 のポジションがあるので、このような複数のクエリを持つことは現実的ではありません。

レールでは、現在このメソッドを使用していますChart.rb

def table
  (1..5).each do |i|
    chart_entries.where(position: i).order('entered_at DESC').first
  end
end

次のSQLを生成します

SELECT "chart_entries".* FROM "chart_entries" WHERE "chart_entries"."chart_id" = 1 AND "chart_entries"."position" = 1 ORDER BY entered_at DESC LIMIT 1
SELECT "chart_entries".* FROM "chart_entries" WHERE "chart_entries"."chart_id" = 1 AND "chart_entries"."position" = 2 ORDER BY entered_at DESC LIMIT 1
SELECT "chart_entries".* FROM "chart_entries" WHERE "chart_entries"."chart_id" = 1 AND "chart_entries"."position" = 3 ORDER BY entered_at DESC LIMIT 1
SELECT "chart_entries".* FROM "chart_entries" WHERE "chart_entries"."chart_id" = 1 AND "chart_entries"."position" = 4 ORDER BY entered_at DESC LIMIT 1
SELECT "chart_entries".* FROM "chart_entries" WHERE "chart_entries"."chart_id" = 1 AND "chart_entries"."position" = 5 ORDER BY entered_at DESC LIMIT 1

これはテーブル構造です (postgresql)

CREATE TABLE chart_entries (
  id integer NOT NULL,
  chart_id integer,
  entity_id integer,
  "position" integer,
  entered_at timestamp without time zone,
  locale character varying(255)
);

CREATE TABLE charts (
  id integer NOT NULL,
  name character varying(255)
);

これが私の最終的な解決策でした

chart_entries.where(position: [1..5]).group('position, id').having('entered_at = MAX(entered_at)').order('position ASC')
4

2 に答える 2