0

私はモデルラップを持っています:

class Lap < ActiveRecord::Base
  belongs_to :car

  def self.by_carmodel(carmodel)
    scoped = joins(:car_model).where(:car_models => {:name => carmodel})
    scoped
  end

  def self.fastest_per_car
    scoped = select("laps.id",:car_id, :time, :mph).group("laps.id", :car_id, :time, :mph).order("time").limit(1)
    scoped
  end
end

各車の最速ラップのみを返したい。

そのため、Lap.car_id でラップをグループ化し、その車に基づいて最速のラップ タイムのみを返す必要があります。これは、Lap.time 列によって決定されます。

基本的に、メソッドをコントローラーにスタックしたいと思います。

@corvettes = Lap.by_carmodel("Corvette").fastest_per_car

うまくいけば、それは理にかなっています...

Lap.fastest_per_carだけを実行しようとすると、各車ごとに 1 つの結果ではなく、すべてを 1 つの結果に制限しています。

私がしなければならなかったもう1つのことは、「laps.id」を追加することでした。結果にも:idが空で表示されていたからです。select(:id) だけだとあいまいだと言っていた

4

3 に答える 3

1

これに対する適切なアプローチは、単一の最速ラップを返すための効率的な SQL 構文に基づいて where 句を追加することだと思います。

この相関サブクエリのようなもの...

select ...
from   laps
where  id = (select   id
             from     laps laps_inner
             where    laps_inner.car_id = laps.car_id
             order by time asc,
                      created_at desc
             limit    1)

created_at でタイブレークする必要があるため、少し複雑です。

Rails のスコープは次のようになります。

where("laps.id = (select   id
                  from     laps laps_inner
                  where    laps_inner.car_id = laps.car_id
                  order by time asc,
                           created_at desc
                  limit    1)")

car_id のインデックスは非常に重要であり、それが (car_id, time asc) の複合インデックスである場合は、はるかに優れています。

于 2013-08-27T18:19:08.807 に答える
0

単一の値を返す limit を使用しています。車ごとに 1 つの値ではありません。ラップごとに 1 つの車の値を返すには、テーブルを結合し、1 つのラップを識別する列のグループでグループ化するだけです (id が最も単純です)。

また、次のようにすると、より ActiveRecord との親和性を高めることができます。

class Lap < ActiveRecord::Base
  belongs_to :car

  def self.by_carmodel(carmodel)
    joins(:car_model).where(:car_models => {:name => carmodel})
  end

  def self.fastest_per_car
    joins(:car_model)
      .select("laps.*, MIN(car_models.time) AS min_time")
      .group("laps.id")
      .order("min_time ASC")
  end
end
于 2013-08-27T21:58:45.777 に答える