【问题标题】:Group Query with Calculations on Rails 3在 Rails 3 上使用计算进行分组查询
【发布时间】:2010-08-27 21:43:41
【问题描述】:

Rails 3 问题。 我有一个具有以下属性的食物表:

  • 姓名
  • 卡路里(每克)
  • 脂肪(每克)
  • 碳水化合物(每克)
  • 蛋白质(每克)

然后我有一个 LoggedFoods 表,表示在给定时间吃过的食物。它具有以下属性:

  • food_id
  • number_of_grams_eaten
  • ate_when(日期时间)

所以我遇到的问题是,我想在一个查询中获得每天(所有天)消耗的卡路里、脂肪、蛋白质、碳水化合物的总数。我一直在尝试使用新的 ActiveRecord 查询界面来执行此 Rails 3,但没有运气。有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails activerecord group-by arel


    【解决方案1】:

    这是一个快速的第一次通过,可能存在一些错误,但数字似乎一目了然。另外:我只在 sqlite3 上测试过,所以在其他数据库上的结果可能会有所不同(以防 SUM 或组函数不同)

    app/models/logged_food.rb

    class LoggedFood < ActiveRecord::Base
      belongs_to :food
    
      def self.totals_by_day(date)
        start_time = Time.parse(date).beginning_of_day
        end_time = Time.parse(date).end_of_day
    
        t = LoggedFood.arel_table
    
        totals = LoggedFood.
          where(t[:ate_when].gteq(start_time)).
          where(t[:ate_when].lteq(end_time)).
          joins(:food).
          select("SUM(calories * grams_eaten) as total_calories").
          select("SUM(fat * grams_eaten) as total_fat").
          select("SUM(carbs * grams_eaten) as total_carbs").
          select("SUM(protien * grams_eaten) as total_protien")
    
        return nil if totals.empty?
    
        {
          :total_calories => totals.first.total_calories, 
          :total_fat => totals.first.total_fat,
          :total_carbs => totals.first.total_carbs,
          :total_protien => totals.first.total_protien
        }
    
      end
    
    end
    

    db/seeds.rb(我显然不知道食物的营养信息)

    @pizza = Food.create(:name => "pizza", :calories => 500, :fat => 10, :carbs => 20, :protien => 30)
    @hot_dog = Food.create(:name => "hot dog", :calories => 400, :fat => 10, :carbs => 20, :protien => 30)
    @apple = Food.create(:name => "apple", :calories => 100, :fat => 1, :carbs => 2, :protien => 3)
    @banana = Food.create(:name => "banana", :calories => 100, :fat => 2, :carbs => 4, :protien => 6)
    
    LoggedFood.create(:food_id => @pizza.id, :grams_eaten => 10, :ate_when => Time.now)
    LoggedFood.create(:food_id => @apple.id, :grams_eaten => 10, :ate_when => Time.now)
    LoggedFood.create(:food_id => @banana.id, :grams_eaten => 10, :ate_when => 12.hours.ago)
    LoggedFood.create(:food_id => @apple.id, :grams_eaten => 10, :ate_when => 1.day.ago)
    LoggedFood.create(:food_id => @pizza.id, :grams_eaten => 10, :ate_when => 2.days.ago)
    LoggedFood.create(:food_id => @banana.id, :grams_eaten => 10, :ate_when => 36.hours.ago)
    LoggedFood.create(:food_id => @hot_dog.id, :grams_eaten => 10, :ate_when => 2.days.ago)
    LoggedFood.create(:food_id => @banana.id, :grams_eaten => 10, :ate_when => 50.hours.ago)
    

    然后在控制台中:

    ree-1.8.7-2010.02 > LoggedFood.totals_by_day("2010-08-27")
      LoggedFood Load (0.2ms)  SELECT SUM(calories * grams_eaten) as total_calories, SUM(fat * grams_eaten) as total_fat, SUM(carbs * grams_eaten) as total_carbs, SUM(protien * grams_eaten) as total_protien FROM "logged_foods" INNER JOIN "foods" ON "foods"."id" = "logged_foods"."food_id" WHERE ("logged_foods"."ate_when" >= '2010-08-27 04:00:00.000000') AND ("logged_foods"."ate_when" <= '2010-08-28 03:59:59.999999') LIMIT 1
     => {:total_fat=>130, :total_protien=>390, :total_calories=>7000, :total_carbs=>260} 
    
    ree-1.8.7-2010.02 > LoggedFood.totals_by_day("2010-08-26")
      LoggedFood Load (0.3ms)  SELECT SUM(calories * grams_eaten) as total_calories, SUM(fat * grams_eaten) as total_fat, SUM(carbs * grams_eaten) as total_carbs, SUM(protien * grams_eaten) as total_protien FROM "logged_foods" INNER JOIN "foods" ON "foods"."id" = "logged_foods"."food_id" WHERE ("logged_foods"."ate_when" >= '2010-08-26 04:00:00.000000') AND ("logged_foods"."ate_when" <= '2010-08-27 03:59:59.999999') LIMIT 1
     => {:total_fat=>30, :total_protien=>90, :total_calories=>2000, :total_carbs=>60} 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-12
      • 2010-12-07
      • 2019-04-24
      • 1970-01-01
      • 2020-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多