本文详解如何使用 yii2 query 构建精准的“今日销售额”查询,避免因时间戳精度、分组逻辑或字段误用导致的统计偏差,确保即使当日无订单也能返回 `0` 而非昨日数据。
要准确获取 MySQL 表中 orders 表今日(仅限当前日期,忽略具体时分秒)已完成订单的 price 字段总和,关键在于:不能依赖 G 
✅ 正确做法是:在 WHERE 子句中显式限定今日的时间范围,并使用 COALESCE(SUM(price), 0) 确保无记录时返回 0。
以下是推荐的 Yii2 实现(兼容 Unix 时间戳与 DATETIME 字段):
public function getTotalEarningsToday()
{
$todayStart = strtotime(date('Y-m-d 00:00:00')); // 今日 00:00:00 时间戳
$todayEnd = strtotime(date('Y-m-d 23:59:59')); // 今日 23:59:59 时间戳
$records = (new Query())
->select(['COALESCE(SUM(price), 0) AS total', 'DATE(FROM_UNIXTIME(updated_at)) AS day'])
->from(Orders::tableName())
->where([
'AND',
['status' => Orders::STATUS_COMPLETED],
['>=', 'updated_at', $todayStart],
['<=', 'updated_at', $todayEnd],
])
->groupBy('day') // 可选:确保单日聚合
->one(); // 使用 one() 而非 all(),因只查今日一行
// 若无记录,$records 为 false → 手动补全
if (!$records) {
return ['total' => 0, 'day' => date('Y-m-d')];
}
return $records;
}public function getTotalEarningsToday()
{
$today = date('Y-m-d');
$records = (new Query())
->select(['COALESCE(SUM(price), 0) AS total', new \yii\db\Expression("'$today' AS day")])
->from(Orders::tableName())
->where([
'AND',
['status' => Orders::STATUS_COMPLETED],
['>=', 'created_at', $today . ' 00:00:00'],
['<=', 'created_at', $today . ' 23:59:59'],
])
->one();
return $records ?: ['total' => 0, 'day' => $today];
}最终调用示例:
$result = $this->getTotalEarningsToday();
echo "今日销售额:¥{$result['total']}({$result['day']})";
// 输出:今日销售额:¥0(2025-06-15) 或 今日销售额:¥249.50(2025-06-15)此方案逻辑清晰、可读性强、健壮可靠,彻底解决“查到昨日数据而非今日零值”的核心痛点。