根据列值的总和选择可变数量的记录

时间:2014-05-25 17:14:57

标签: sql ruby-on-rails performance

我有一个表格,其列是一个浮点数。 我按created_at命令表: Foo.order(:created_at)

我想从该有序表中选择可变数量的记录。

它的变化因为我需要对记录中的float列的值求和,以获得大于目标float的值。

所以我可以说我已经订购了上面的表格,它有4条记录,其浮动值为:

  1. 30
  2. 50
  3. 40
  4. 20
  5. 如果我的目标浮点数是60,我想只返回前2个记录 如果我的目标浮点数为100,我想返回3条记录 如果我的目标浮点数为20,我只需要第一条记录

    有没有办法在活动记录或直接sql中执行此操作?

    这样做是否更快,或者我应该查询所有记录并仅使用我需要的记录?

    编辑:

    在这个问题的基础上,我想从他们的一个列中首先排序的表中选择让我们说fizz:

    select foo1.id, 
        (select coalesce(sum(f2.amount),0) 
         from (select * from foo order by fizz) f2 
         where f2.id < f1.id) as amount_total 
    from (select * from foo order by fizz)
    group by f1.id
    having amount_total < target_total
    

    这是有效的,但并不理想,因为你要两次订购这张桌子。有没有办法订购一次表,然后将它用于f1和f2?

2 个答案:

答案 0 :(得分:0)

也许会做这样的事情:

def check_sum(target)
   if target == 60.00
     return Foo.order(:created_at).limit(2)
   elsif target == 100.00
     return Foo.order(:created_at).limit(3)
   elsif target == 20.00
     return Foo.order(:created_at).limit(1)
   end
end

您也可以对其进行排序ASC / DESC示例Foo.order("created_at DESC")

答案 1 :(得分:0)

假设表格foo包含idbarfizz列:

id bar fizz
-- --- ----
1  30  3
2  50  2
3  40  1
4  20  4

您可以在SQL中执行此操作,但我认为您无法在ActiveRecord中执行此操作。

select f1.id, f1.bar, f1.fizz, 
       (select coalesce(sum(f2.bar),0) 
          from foo f2 
         where f2.fizz < f1.fizz) as bar_total 
  from foo f1 
 group by f1.id, f1.bar, f1.fizz
having bar_total < TEST_VALUE
 order by f1.fizz;

注意:正如下面的评论所指出,您可能需要也可能不需要group by条款。 sqlite3需要它,但mysql不需要。

例如,如果TEST_VALUE = 60:

id bar fizz bar_total
-- --- ---- -------------
3  40  1    0
2  50  2    40

如果TEST_VALUE = 100:

id bar fizz bar_total
-- --- ---- -------------
3  40  1    0
2  50  2    40
1  30  3    90

如果TEST_VALUE = 20:

id bar fizz bar_total
-- --- ---- -------------
3  40  1    0