数据库中的group by与rails中的group_by的区别及使用方法

group by是关系型数据库中较为常用的方法,rails也提供了类似的group_by方法,但两者还是有不小区别的,下面我们通过一个实例说明一下:

有一张表: orders,包含这些字段,
用户ID: user_id
商品ID: product_id
购买数量: amount
购买时间: buy_at

user_id product_id amount buy_at
1 1 3 2015-05-05
1 2 4 2015-05-05
2 1 5 2015-05-05
2 2 6 2015-05-06

先简单说一下数据库中group by的用法,顾名思义,就是分组的意思。使用了group by,那SQL语句的select部分,只能写sum或者count这类函数(只有被group by的字段可以直接取),因为数据库已经把所有记录按照指定条件进行了分组,每组其实就是一条记录(由符合该组条件的一条或者多条数据转变而来),比如:

select user_id, sum(amount) from orders group by user_id
此时得到的结果就是:

user_id amount
1 7
2 11

在使用group by之前,可以正常使用where来对需要group by的数据进行预筛选,如果还需要对group by之后的数据再次进行筛选,可以在group by 之后使用having:

select user_id, sum(amount) as total_amount from orders where amount >=4 group by user_id having total_amount >=8
这句句子很好理解,先从全部四条数据中,选出购买数量大于等于4的订单(第一条数据被去掉了),然后按照上面的方法进行分组,分组后结果显示是:

user_id amount
1 4
2 11

最后再次筛选出购买总数大于等于8的数据,那分组结果中的第一条数据又被去掉了,符合条件的只剩第二条了

如果用rails的find_by_sql来取数据:

@orders = Order.find_by_sql(["select user_id, sum(amount) from orders group by user_id"])
此时如果看@orders.size的话,应该是2,只有两条数据

这个时候,我们再看一下rails提供的order_by方法:

@orders = Order.all.group_by{|o|o.user_id}
此时我们得到的结果是这样的:
{1=>[#, #], 2=>[#, #]}

结果很明显,返回了一组Hash,key是user_id,value是等于这个user_id的所有实例对象,个人认为rails中的group_by,更符合“分组”这个词的本义,并没有去合并或者计算数据,而且根据要求进行了单纯的分组处理。我们拿第一条数据来看一下:

@orders.first
1=>[#, #]
@orders.first[0]
3
@orders.first[1]
[#, #]
此时又能对@orders.first[1]进行.each来迭代输出数据了

总结一下:两种group by,不存在好与坏,因为应用的场景不同,善于利用group by,在某些场景下可以大大减少对数据库的查询次数,提高页面的执行效率。

你可能感兴趣的:(数据库中的group by与rails中的group_by的区别及使用方法)