我有最简单的查询,我正在尝试运行
DB::table('user_visits')->groupBy('user_id')->count();
但它返回了错误的数字,8。
如果我将其更改为:
count(DB::table('user_visits')->groupBy('user_id')->get());
然后它返回正确的数字,34。为什么这些值不相同?
这是我的表结构
user_visits( user_id, date_visited, num_clicks )
答案 0 :(得分:32)
关于调试的说明
这两种不同方法生成的查询完全不同,这就是为什么会发生这种情况的原因。每当遇到数据库问题时,查看基础查询日志总是一个好主意,这样你就可以看到正在执行的操作:
dd(DB::getQueryLog());
将打印出查询日志,如果你在违规查找后立即执行,你可以直接到日志的末尾查看最新查询(即如果你在第二次查找后放置它,那么最后一次查询日志将是你的包装计数器,最后一个查询将是计数方法。
您的具体问题
无论如何,要解释你的具体问题。正在生成的两个查询将类似于
DB::table('user_visits')->groupBy('user_id')->count();
// SELECT COUNT(*) from user_visits GROUP BY user_id
这将返回每个组中的条目数。 mysql正在做的是通过user_id列对所有行进行分组,然后每组返回一行计数。如果我们将“user_id”添加到列中以供选择,并针对您的数据库手动运行查询,那么您可能会看到类似这样的结果
// SELECT user_id, COUNT(*) FROM user_visits GROUP BY user_id
----------------------
| user_id | COUNT(*) |
----------------------
| 1 | 8 |
| 2 | 4 |
| 5 | 11 |
----------------------
您的第二个查询不同
DB::table('user_visits')->groupBy('user_id')->get()
// SELECT * FROM user_visits GROUP BY user_id
这是做什么的,只是选择所有条目,对它们进行分组并返回它们。这导致每个用户id返回一行,该行包含该user_id的一个条目的所有信息(它可能是该用户的第一个条目,它可能是最后一个,它可能是随机的,虽然没关系。
您的count()
会计算返回的行数,这将是唯一user_id的计数。
因此,您的第一个查询是计算每组有多少user_id(当您尝试打印结果时,laravel将返回第一条记录,这会导致显示结果集中第一个user_id的条目数),并且您的第二个查询(加上应用的计数函数)返回找到的组数(即唯一user_id的数量)。
使用上面的表格来说明这一点......
查询1:对于结果集
中的第一个条目,将返回“8”,因为这是计数
查询2:对于结果集中的行数
想要正确的号码,而不加载所有数据?
如果您希望根据第二个查询获得正确的结果,但想要查询1的轻量级,网络较重的单个整数响应,则可以执行以下操作:
DB::table('user_invites')->count(DB::raw('DISTINCT user_id'))
导致:
SELECT COUNT(DISTINCT user_id) FROM user_visits;
希望一切都有道理,让我的头脑有点困惑我确定
答案 1 :(得分:3)
您可以尝试这样做,因为group by
语句是在count
(Bug #26209)之后执行的:
DB::table('user_visits')->distinct('user_id')->count('user_id');
这里有另一个mySql answer。