20
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RubyAdvent Calendar 2013

Day 13

データ出してくれって言われたときに便利なテクニック

Last updated at Posted at 2014-01-09

こんな感じのモデルの時

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の上でしかコード書いてないのでバグがないか自信なし。

20
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?