【问题标题】:laravel use count/sum method after groupBylaravel 在 groupBy 之后使用 count/sum 方法
【发布时间】:2016-10-26 14:10:50
【问题描述】:

当我使用countsum 方法时,我得到了错误的结果。

例如:

Member::groupBy('id')->count()

我只得到结果1,用另一种方法

Member::count()

我得到了正确的结果。

我在使用sum 方法时得到了错误的结果。

https://github.com/laravel/framework/issues/14123

忘了说,我的 laravel 版本信息:

Laravel Framework version 5.1.40 (LTS)



项目中的实际问题

我有一个充值日志表

1.支付日志表

CREATE TABLE pay_logs (
   id int(11) NOT NULL AUTO_INCREMENT,
   amount decimal(20,2) DEFAULT '0.00',
   pay_sn varchar(20) DEFAULT NULL,
   join_date int(11) unsigned DEFAULT '0',
   PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

1.1 支付日志数据

INSERT INTO pay_logs (id, amount, pay_sn, join_date)
VALUES
  (1,10.00,'aabbcc',1466753291),
  (2,10.00,'aabbcc',1466753292),
  (3,20.00,'bbccdd',1466753292),
  (4,30.00,'ccddee',1466753292);

2.描述

在 pay_log 表中,1 和 2 记录是相同的。所以当想通过实际充值成功时间来过滤结果时,我只需要一条记录,所以我使用groupBy操作。

我的错误操作

DB::table('pay_log')
 ->whereBetween('joinDate',[$beginToday,$endToday])
 ->where('isSucceed','=',1)
 ->where('type','=',1)
 ->groupBy('pay_sn');
 ->count();

终于解决了。

$query = DB::table('pay_log')
 ->select(DB::raw('count(*) as num'))
 ->whereBetween('joinDate',[$beginToday,$endToday])
 ->where('isSucceed','=',1)
 ->where('type','=',1)
 ->groupBy('pay_sn');

ps:如果使用 Eloquent ORM

->mergeBindings($query)修改为->mergeBindings($query->getQuery())



测试示例(丢弃

  1. 创建表sql

    CREATE TABLE members ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(15) DEFAULT NULL, amount decimal(20,2) DEFAULT '0.00', PRIMARY KEY (id) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

  2. 测试数据

    INSERT INTO hc_members (id, name, amount) VALUES (1,'aaa',10.00), (2,'bbb',10.00), (3,'ccc',10.00);

  3. 测试结果

希望当我使用Member::groupBy('name')->count()这个方法时

我想要结果 3

实际上它返回 1


当我使用方法Member::groupBy('name')->sum('amount')

我想要结果 30.00

实际上它返回 10.00



感谢您的回答帮助我解决问题!

【问题讨论】:

  • 为什么不使用count(Member::groupBy('id')->get())
  • 因为Illuminate\Database\Eloquent\Collection 提供->count() 是出于特定原因。
  • @Ohgodwhy 但是与groupBy()结合使用时似乎并没有给出正确的结果
  • @aldrin27 谢谢你的回答。正如你所说,我可以使用你的方法(但我得到 500 错误,可能内存不足,获取太多数据,我认为没有必要,我只需要获取它有多少记录)我有同样的问题 @987654342 @方法,我该如何解决。
  • @Uchiha 我已经编辑了我的描述。

标签: php laravel count group-by sum


【解决方案1】:

这不是 laravel 的问题,因为 Member::groupBy('id')->count() 将返回每个 id 的结果数。 (Laravel 只返回查询结果的第一行。)

尝试运行此查询

SELECT COUNT(*) AS aggregate FROM members GROUP BY 'id'

它将返回每个 (id) 聚合的行数。这是当你调用 Member::groupBy('id')->count() 和 laravel 时执行的查询,期望只有一行,返回第一个聚合的计数。

如果你想计算不同的 id,你可以调用

Member::distinct('id')->count('id')

这与您的 sum 查询也返回 10 的原因相同。该查询返回具有相同“名称”的组的“金额”总和。

要获得所有金额的总和,只需调用,

Member::sum('amount');

【讨论】:

  • 感谢您的回答,如何获取行号。 sql:select count(*) from memebr group by idlaravel怎么写
  • 这是你调用Member::groupBy('id')->count()时执行的查询。如果要获取不同 id 的计数,可以致电 Member::select('id')->distinct()->count('id')。 (我假设这是您需要的结果)
  • 无论何时调用get(),实际上都是在执行一个返回查询结果集合的查询。这通常会消耗您的所有内存并挂起您的应用程序。另一方面,在您调用get() 或类似函数之前,您的查询只是一个查询。它没有被执行,你不必担心一个庞大的集合会耗尽你的记忆。
  • 您说您期望“30”,但您希望如何获得该结果?您是否希望汇总所有金额或其他内容,因为这是在这种情况下获得该结果的唯一方法。
  • 感谢您的专业回答。我将编辑我的问题,即为什么我必须在 countsum 方法之前使用 groupBy。对不起我的模棱两可的描述。
猜你喜欢
  • 1970-01-01
  • 2019-02-02
  • 2011-03-25
  • 1970-01-01
  • 1970-01-01
  • 2022-10-12
  • 2019-06-20
  • 2021-11-13
相关资源
最近更新 更多