こんな感じのモデルの時
User
* id
* name
* money
Pet
* id
* user_id
* name
Food
* id
* name
Meal
* id
* pet_id
* food_id
* created_at
ポイント
- 基本、rails consoleで出す
- 早さが重要
- 言われる前に関係あることもついでに出す
例1) シュナウザー飼ってる人ってどのくらいいるの?
a = Pet.where(name: "シュナウザー").select(:user_id).uniq
result = a.count
例2) シュナウザー飼ってる人っていくらくらい持ってるの?
b = User.where(id: a)
result = b.select("avg(*)")
例3) シュナウザー飼ってて1000万以上お金持ってる人って自分でペットに餌上げてる人っているの?
c = Pet.where(id: Meal.select(:pet_id).uniq) # ペット飼って餌上げてる人
d = b.where("money > 1000万").where(id: c.select(user_id))
result = d.count
例4) シュナウザー飼ってて1000万以上お金持ってる人で、ペットに餌上げてる人って今年月何回くらい平均餌上げてるの?
e = Pet.where(user_id: d.select(:id)) # シュナウザー飼ってて1000万以上お金持ってる人で、餌もらってるペット。
f = Meal.group("month, pet_id").select("count(*)").select("pet_id")
.select("DATE_TRUNC('month', meals.created_at) AS month") # 月ごとペットごとに食べている餌の数
result = e.joins("JOIN (#{f.to_sql}) AS table ON table.pet_id = pets.id")
.group("table.month").select("avg(table.count)")
コツ
- パーツに分けて出力する
- エラーがでたら、to_sqlしてなにが違うか確認する
- groupやjoinよりwhereで書くほうがあとあと使いやすい
- 最速なコードより最速で結果を見せるのが重要
これなら全部お願いされても10分以内にデータ出せるでしょ!!
でもqiitaの上でしかコード書いてないのでバグがないか自信なし。