
本文详解如何使用 yii2 query 构建精准的“今日销售额”查询,避免因时间戳精度、分组逻辑或字段误用导致的统计偏差,确保即使当日无订单也能返回 `0` 而非昨日数据。
要准确获取 MySQL 表中 orders 表今日(仅限当前日期,忽略具体时分秒)已完成订单的 price 字段总和,关键在于:不能依赖 GROUP BY + ORDER BY + LIMIT 1 的组合逻辑——该方式会返回「最近有数据的那一天」,而非「今天」;同时,直接用 FROM_UNIXTIME(updated_at, '%Y-%m-%d') 在 WHERE 条件中做匹配也不可行,因其属于表达式字段,无法高效利用索引且易引发类型隐式转换问题。
✅ 正确做法是:在 WHERE 子句中显式限定今日的时间范围,并使用 COALESCE(SUM(price), 0) 确保无记录时返回 0。
以下是推荐的 Yii2 实现(兼容 Unix 时间戳与 DATETIME 字段):
✅ 方案一:updated_at 为 Unix 时间戳(INT 类型)
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;
}✅ 方案二:created_at / updated_at 为 DATETIME 类型(更推荐)
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];
}⚠️ 注意事项:
- 勿用 FROM_UNIXTIME(...) 在 WHERE 中做等值匹配:如 'updated_at' => strtotime('2022-02-21') 仅匹配 updated_at = 1645401600(即恰好整日零点),而实际订单时间戳多为 1645412345,必然漏查。
- 优先使用 created_at 而非 updated_at:订单完成状态变更可能触发 updated_at 更新,但销售额应归属下单日(即 created_at)。
- 必须用 COALESCE(SUM(...), 0):MySQL 中 SUM() 对空结果集返回 NULL,需转为 0 才符合业务预期。
- 索引优化建议:为 (status, created_at) 建联合索引,大幅提升查询性能。
最终调用示例:
立即学习“PHP免费学习笔记(深入)”;
$result = $this->getTotalEarningsToday();
echo "今日销售额:¥{$result['total']}({$result['day']})";
// 输出:今日销售额:¥0(2024-06-15) 或 今日销售额:¥249.50(2024-06-15)此方案逻辑清晰、可读性强、健壮可靠,彻底解决“查到昨日数据而非今日零值”的核心痛点。











