は、次のSQLの方が大きいのcreated_atと行がない行のみを選択して、あなたのおそらく最も効率的な方法
になるだろうに参加します。
詳細はこの記事を参照してください:https://stackoverflow.com/a/27802817/5301717
query = <<-SQL
SELECT m.* # get the row that contains the max value
FROM services m # "m" from "max"
LEFT JOIN services b # "b" from "bigger"
ON m.available_id = b.available_id # match "max" row with "bigger" row by `home`
AND m.available_type = b.available_type
AND m.created_at < b.created_at # want "bigger" than "max"
WHERE b.created_at IS NULL # keep only if there is no bigger than max
AND service.available_type = 'User'
SQL
Service.find_by_sql(query)
明瞭には、引数として偽/唯一の真の列名を取りません。
distinctは、別個のレコードのみを返すためのもので、特定の値のフィルタリングとは関係ありません。
あなたが特定のavailable_id
が必要な場合、あなたはwhere
例えばを使用する必要があります最初の異なる多型の値を取得するループ
が必要になりますだけでは、各個別のavailable_idの最新を取得する必要がある場合は、最新のlimit
Service.distinct.where(available_type: "User").where(available_id: YOUR_ID_HERE).order(created_at: :desc).limit(1)
を追加取得するには
Service.distinct.where(available_type: "User").where(available_id: YOUR_ID_HERE).order(created_at: :desc)
、区別する必要がある列を選択するだけでselect
:
available_ids = Service.distinct.select(:available_id).where(available_type: 'User')
は、各IDの最新のを取得:
recents = []
available_ids.each do |id|
recents << Service.where(available_id: id).where(available_type: 'User').order(created_at: :desc).limit(1)
end
ありがとうございました。このソリューションはどのように優れていますか? – Andrew
レコードの数に関係なく、任意の時点で2つの連続したクエリが生成されます。一方、もう1つの解決策は明らかにn + 1 ... –
この解決策は、最新のものを取得していません:created_at。最大の:idのみ。ほとんどの場合、これらは同じものですが、:idと:idを入れ替えようと思っているかもしれません。created_at – TheRealMrCrowley