
本文详解如何通过修正 sql 条件逻辑,正确按月份和木材型号(如 a-001、a-003)分别汇总立方米(cubic)数据,并在 html 表格中动态渲染结果。
在实际木材加工或仓储管理系统中,常需按月统计不同木材类型的出库/加工量(单位:m³)。你当前遇到的核心问题是:SQL 中误将 cubic 字段用于 IF() 的判断条件,而实际应根据 wood 字段匹配型号,再对 cubic 值求和。原始查询中 SUM(IF(cubic='A-001',1,0)) 本质是在计数(且逻辑错误),而非累加体积值——这导致所有分类列显示为 0.0 m³,仅 SUM(cubic) 正确。
✅ 正确做法是:使用 SUM(IF(wood = 'A-001', cubic, 0)) —— 即当 wood 字段匹配特定型号时,取其对应的 cubic 数值参与求和;否则计入 0。同时注意:
- MySQL 中小数分隔符为英文句点(.),但你的示例数据使用了逗号(,),请确保数据库中 cubic 列为 DECIMAL 或 FLOAT 类型,且数据已规范存储(如 0.25 而非 0,25),否则会导致隐式转换失败或求和异常;
- MONTH(date) 仅返回月份数字(1–12),若需显示“2月”等中文名称,可在 PHP 中映射处理;
- WHERE machine='mebor2' 与示例数据中的 mebor1 不一致,请根据实际需求调整过滤条件。
以下是修正后的完整 PHP + MySQL 实现代码(含健壮性增强):
<div class="col-sm">
<table class="table table-sm">
<thead>
<tr>
<th scope="col">月份</th>
<th scope="col">Nyár</th>
<th scope="col">Tölgy</th>
<th scope="col">VTölgy</th>
<th scope="col">Cser</th>
<th scope="col">合计</th>
</tr>
</thead>
<tbody>
<?php
// ✅ 修正后的 SQL:按 wood 匹配,对 cubic 求和
$sql_list = "
SELECT
MONTH(date) AS month,
COUNT(DISTINCT DATE(date)) AS work_days,
COALESCE(SUM(IF(wood = 'A-001', cubic, 0)), 0) AS sum_nyar,
COALESCE(SUM(IF(wood = 'A-003', cubic, 0)), 0) AS sum_tolgy,
COALESCE(SUM(IF(wood = 'A-004', cubic, 0)), 0) AS sum_vtolgy,
COALESCE(SUM(IF(wood = 'A-018', cubic, 0)), 0) AS sum_cser,
COALESCE(SUM(cubic), 0) AS sum_full
FROM furesz
WHERE machine = 'mebor2'
AND date >= DATE_SUB(NOW(), INTERVAL 12 MONTH) -- 可选:限制近一年数据
GROUP BY month
ORDER BY month ASC";
$result_list = mysqli_query($conn, $sql_list);
if (!$result_list) {
echo "<tr><td colspan='6'>查询失败:" . mysqli_error($conn) . "</td></tr>";
} elseif (mysqli_num_rows($result_list) === 0) {
echo "<tr><td colspan='6'>暂无数据</td></tr>";
} else {
while ($row = mysqli_fetch_assoc($result_list)) {
// 将数字月份转为中文(可选)
$monthName = ['1月','2月','3月','4月','5月','6月',
'7月','8月','9月','10月','11月','12月'][$row['month'] - 1] ?? $row['month'] . '月';
?>
<tr>
<th scope="row"><?= htmlspecialchars($monthName) ?></th>
<td><?= number_format($row['sum_nyar'], 2, '.', '') ?> m³</td>
<td><?= number_format($row['sum_tolgy'], 2, '.', '') ?> m³</td>
<td><?= number_format($row['sum_vtolgy'], 2, '.', '') ?> m³</td>
<td><?= number_format($row['sum_cser'], 2, '.', '') ?> m³</td>
<th><?= number_format($row['sum_full'], 2, '.', '') ?> m³</th>
</tr>
<?php
}
}
?>
</tbody>
</table>
</div>? 关键改进说明:
立即学习“PHP免费学习笔记(深入)”;
- 使用 COALESCE(..., 0) 防止 NULL 值在前端显示为空白;
- number_format($val, 2, '.', '') 统一使用英文小数点,避免 locale 导致格式混乱;
- 添加 htmlspecialchars() 防止 XSS(尤其当字段内容可能含用户输入时);
- 增加错误处理与空数据提示,提升生产环境鲁棒性;
- ORDER BY month ASC 确保月份升序排列,便于阅读。
? 进阶建议:
若木材类型较多或动态变化,可考虑用 CASE WHEN 或预聚合视图替代硬编码 IF;更灵活的方案是先查出所有唯一 wood 值,再动态构建列名与 SQL,结合 PDO 的预处理语句实现完全动态报表。











