美文网首页非典型程序员的RailsRuby on Rails
数据库中的group by与rails中的group_by的区别

数据库中的group by与rails中的group_by的区别

作者: TCJ | 来源:发表于2015-06-13 20:14 被阅读1898次

    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=>[#<Order id: 1, user_id: 1, product_id: 1, amount: 3, buy_at: 2015-05-05>, #<Order id: 2, user_id: 1, product_id: 2, amount: 4, buy_at: 2015-05-05>], 2=>[#<Order id: 3, user_id: 2, product_id: 1, amount: 5, buy_at: 2015-05-05>, #<Order id: 4, user_id: 2, product_id: 2, amount: 6, buy_at: 2015-05-06>]}

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

    @orders.first
    1=>[#<Order id: 1, user_id: 1, product_id: 1, amount: 3, buy_at: 2015-05-05>, #<Order id: 2, user_id: 1, product_id: 2, amount: 4, buy_at: 2015-05-05>]
    @orders.first[0]
    3
    @orders.first[1]
    [#<Order id: 1, user_id: 1, product_id: 1, amount: 3, buy_at: 2015-05-05>, #<Order id: 2, user_id: 1, product_id: 2, amount: 4, buy_at: 2015-05-05>]
    此时又能对@orders.first[1]进行.each来迭代输出数据了

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

    相关文章

      网友评论

      • d19b7f381b47:噗,作者是不是把 Rails 的 group 与 group_by 搞混了?

        Rails 的 group 相当于 SQL 的 group_by

        Rails 的 group_by 是为 Enumerable 做的扩展,仅仅只是对数据进行分组,跟 ActiveRecord 没任何关系。
      • 921daab44a8c:看了你讲解,觉得rails里的group_by比较像数据库里的partition by

      本文标题:数据库中的group by与rails中的group_by的区别

      本文链接:https://www.haomeiwen.com/subject/axgjqttx.html