以下是我数据库的结构
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]
表格中的信息(搜索条件)
我需要获得以下计数和信息。
预期结果::'美国'搜索条件: -
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();
答案 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()
都可以为您提供所需的信息。无论什么最适合你的情况。