
本文讲解如何在 php 中通过一次 sql 查询正确关联两个 mysql 表(`be` 和 `brikett_order`),避免因分步查询导致的表格结构错位问题,实现按月份聚合的「生产数」与「订单数」并列展示。
在您的原始代码中,问题根源在于将两个独立查询的结果分别输出到 <tr> 标签的不同位置:第一个 while 循环只输出前三列(<th> + 两个 <td>),第二个 while 循环却直接输出 <td> 到已关闭的 <tr> 外部,导致 HTML 结构混乱(如出现空列、列错位、多行嵌套异常等)。浏览器会自动“修复”非法表格结构,但结果不可控——这正是 sum_order 显示在错误位置甚至被截断的根本原因。
✅ 正确做法是:用一条 SQL 完成关联与聚合,确保每行数据原子性完整。推荐使用 LEFT JOIN,以 be 表为主表(保障所有生产记录不丢失),同时关联满足条件(state='zárt' 且 barcode 和 date 匹配)的订单数据:
SELECT MONTH(be.date) AS month, COUNT(DISTINCT DATE(be.date)) AS work_days, COUNT(*) AS sum_number, COALESCE(SUM(bo.amount), 0) AS sum_order FROM be LEFT JOIN brikett_order bo ON bo.barcode = be.barcode AND bo.date >= DATE(be.date) AND bo.date < DATE_ADD(DATE(be.date), INTERVAL 1 DAY) AND bo.state = 'zárt' WHERE be.barcode = 'R-001' GROUP BY month ORDER BY month;
? 关键优化说明: 使用 COALESCE(SUM(...), 0) 避免 NULL 值显示为空白; JOIN 条件中用 DATE() 范围匹配替代精确 datetime 等值(因两表时间精度可能不同),更符合业务逻辑(同日即匹配); 添加 ORDER BY month 保证结果按自然月序排列。
对应 PHP 渲染部分应完全重构为单循环,确保每行 <tr> 内四列数据一次性输出:
<div class="col-sm">
<h5 class="mt-3">Havi Gyártás</h5>
<table class="table table-sm">
<thead>
<tr>
<th scope="col">Hónap</th>
<th scope="col">Munkanapok</th>
<th scope="col">Gyártás</th>
<th scope="col">Eladás</th>
</tr>
</thead>
<tbody>
<?php
$sql = "SELECT
MONTH(be.date) AS month,
COUNT(DISTINCT DATE(be.date)) AS work_days,
COUNT(*) AS sum_number,
COALESCE(SUM(bo.amount), 0) AS sum_order
FROM be
LEFT JOIN brikett_order bo
ON bo.barcode = be.barcode
AND DATE(bo.date) = DATE(be.date)
AND bo.state = 'zárt'
WHERE be.barcode = 'R-001'
GROUP BY month
ORDER BY month";
$result = mysqli_query($conn, $sql);
if ($result && mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_assoc($result)) {
echo "<tr>
<th scope='row'>{$row['month']}</th>
<td>{$row['work_days']}</td>
<td>{$row['sum_number']} db</td>
<td>{$row['sum_order']} db</td>
</tr>";
}
} else {
echo "<tr><td colspan='4' class='text-muted'>Nincs adat a kiválasztott cikkszámhoz.</td></tr>";
}
?>
</tbody>
</table>
</div>? 注意事项总结:
- ❌ 禁止拆分查询 + 拆分 echo 输出到同一 <tr> —— 这违反 HTML 表格语义;
- ✅ 始终优先考虑 JOIN + GROUP BY 在数据库层完成关联聚合,性能与可维护性远高于 PHP 层拼接;
- ⚠️ 若两表日期字段无严格对齐需求(如只需按月汇总,不强求同日),可将 JOIN 条件中的 DATE() 改为 MONTH() 和 YEAR() 组合,但需注意跨年场景;
- ? 后续扩展建议:为 barcode 和 date 字段添加联合索引,显著提升 GROUP BY 和 JOIN 效率。
通过以上重构,您将获得结构严谨、语义清晰、数据准确的月度生产与销售对比表格,彻底解决 sum_order 错位显示问题。










