
本文详解如何通过单条 sql join 查询合并来自两个表(`be` 和 `brikett_order`)的月度统计结果,并在 php 中生成结构正确的 html 表格,避免因分步查询导致的行错位问题。
在实际开发中,当需要从多个关联表中提取按时间维度(如月份)聚合的数据并统一展示在一张 HTML 表格中时,切忌使用多次独立查询 + 分段输出 <td> 标签的方式——这正是原代码中 sum_order 仅出现在最后一行、表格结构错乱的根本原因。
原逻辑问题分析:
- 第一个 while 循环输出了 <tr> 开始及前三列(month、work_days、sum_number),但未闭合 </tr>;
- 第二个 while 循环单独输出 <td>,导致 HTML 结构断裂,浏览器自动纠错后形成不可控的嵌套或空列;
- 两组数据无显式关联键(如 month 对齐),无法保证相同月份记录顺序一致,极易出现错行。
✅ 正确解法:用一条 SQL 完成关联聚合,PHP 一次循环渲染整行
推荐使用 LEFT JOIN,以 be 表为主表(确保所有生产记录月份均被保留),关联 brikett_order 中状态为 'zárt' 且条码匹配的订单数据:
立即学习“前端免费学习笔记(深入)”;
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.state = 'zárt' AND YEAR(bo.date) = YEAR(be.date) AND MONTH(bo.date) = MONTH(be.date) WHERE be.barcode = 'R-001' GROUP BY MONTH(be.date) ORDER BY month;
? 关键优化说明:使用 YEAR() 和 MONTH() 同时匹配,避免跨年同月误关联;COALESCE(SUM(...), 0) 确保无订单月份显示为 0 而非 NULL;ORDER BY month 保障结果按自然月份升序排列。
对应 PHP 渲染代码(简洁、健壮、语义清晰):
<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 bo.state = 'zárt'
AND YEAR(bo.date) = YEAR(be.date)
AND MONTH(bo.date) = MONTH(be.date)
WHERE be.barcode = 'R-001'
GROUP BY MONTH(be.date)
ORDER BY month";
$result = mysqli_query($conn, $sql);
if (!$result) {
die("Query failed: " . mysqli_error($conn));
}
while ($row = mysqli_fetch_assoc($result)) { ?>
<tr>
<th scope="row"><?= htmlspecialchars($row['month']) ?></th>
<td><?= (int)$row['work_days'] ?></td>
<td><?= (int)$row['sum_number'] ?> db</td>
<td><?= (int)$row['sum_order'] ?> db</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>? 注意事项:
- 始终对数据库输出做 htmlspecialchars() 转义,防止 XSS;
- 使用 (int) 强制类型转换确保数值安全显示;
- 添加 mysqli_error() 错误检查,便于调试;
- 若需支持多条码或动态筛选,应将 'R-001' 替换为预处理参数(PDO/MySQLi prepared statement)。
通过单查询聚合 + 单循环渲染,既提升性能,又彻底解决表格结构错乱问题,是构建可靠数据报表的标准实践。











