Laravel根据groupBy获得结果计数

时间:2013-12-20 09:22:05

标签: php mysql laravel laravel-4

以下是我数据库的结构

id  name  country  province   status  updated_at    
1   A     US       TX         2       [timestamp]
2   B     UK       LON        1       [timestamp]
3   C     US       TX         2       [timestamp]
4   D     US       WA         2       [timestamp]
5   E     US       WA         3       [timestamp]
6   F     US       WA         2       [timestamp]
7   G     US       TX         1       [timestamp]

表格中的信息(搜索条件)

  • 此示例中的国家/地区(美国)
  • 开始日期,结束日期

我需要获得以下计数和信息。

  • 按省份分组{
    • $ ca = count(状态'1')
    • $ cb = count(状态'2')
    • $ cc = count(status'3')}

预期结果::'美国'搜索条件: -

Province TX
    Status '1': 1
    Status '2': 2
    Status '3': 0

Province WA
    Status '1': 0
    Status '2': 2
    Status '3': 1

以下是我尝试但失败的原因

$users = DB::table('users')
->where('country', $b)
->select('province', DB::raw('count(*) as total'))
->groupBy('province')
->whereBetween('updated_at', [
        \Carbon\Carbon::createFromDate($d, $e)->startOfMonth(),
        \Carbon\Carbon::createFromDate($f, $g)->endOfMonth()
    ])->orderBy('created_at','desc')->get();

1 个答案:

答案 0 :(得分:0)

注意:我的原始MySQL有点生疏,对任何错误都道歉。

问题1:您按错误的列进行分组。

如果您想知道每个国家/地区的每个省的每个州的总数,则需要在GROUP BY子句中指定所有这些项目。事实上,您的COUNT将确定唯一省份的数量。

GROUP BY country, province, status

问题2:没有条目的状态不会显示。

除非您为每个状态加入外部表,否则您不会对不存在的状态进行任何计数。根据您提供的数据,原始结果看起来更像是:

Country  Province  Status  Total
US       TX        1       1
US       TX        2       2
US       WA        2       2
US       WA        3       1

Here's an example如何为不存在的条目实现零计数。使用它完全取决于您的数据和数据库结构。

潜在警告:ORDER BY

created_at列排序似乎毫无意义。如果您希望获得预期的结果,则需要根据该信息专门订购:

ORDER BY country, province, status

<强>解决方案

我不会包含联接来检索任何零结果状态。但这是一个未经测试的如何转换为查询生成器的示例:

$results = DB::table('users')
    ->select(['country', 'province', 'status', DB::raw('COUNT(*) AS total')])
    ->where('country', '=', $b)
    ->whereBetween('updated_at', [
        \Carbon\Carbon::createFromDate($d, $e)->startOfMonth(),
        \Carbon\Carbon::createFromDate($f, $g)->endOfMonth()
    ])
    ->groupBy('country', 'province', 'status')
    ->orderBy('country') // defaults to ASC
    ->orderBy('province')
    ->orderBy('status')
    ->get();

替代解决方案

半复杂查询的替代方法可能是简单地查询您需要的信息集(属于$b国家/地区的条目,以及在提供的updated_at次之间),然后处理它你自己在PHP。

Laravel的Collection类内置了方便的数据转换方法。这些,甚至是原始的foreach()都可以为您提供所需的信息。无论什么最适合你的情况。