MySQL 数据查询结果合并显示为完整 HTML 表格的正确实现方法

本文详解如何通过单条 sql join 查询合并来自两个表(`be` 和 `brikett_order`)的月度统计结果,并在 php 中生成结构正确的 html 表格,避免因分步查询导致的行错位问题。

在实际开发中,当需要从多个关联表中提取按时间维度(如月份)聚合的数据并统一展示在一张 HTML 表格中时,切忌使用多次独立查询 + 分段输出 标签的方式——这正是原代码中 sum_order 仅出现在最后一行、表格结构错乱的根本原因。

原逻辑问题分析:

  • 第一个 while 循环输出了 开始及前三列(month、work_days、sum_number),但未闭合 ;
  • 第二个 while 循环单独输出 ,导致 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 渲染代码(简洁、健壮、语义清晰):

      
    Havi Gyártás
    Hónap Munkanapok Gyártás Eladás
    db db

    ? 注意事项:

    • 始终对数据库输出做 htmlspecialchars() 转义,防止 XSS;
    • 使用 (int) 强制类型转换确保数值安全显示;
    • 添加 mysqli_error() 错误检查,便于调试;
    • 若需支持多条码或动态筛选,应将 'R-001' 替换为预处理参数(PDO/MySQLi prepared statement)。

    通过单查询聚合 + 单循环渲染,既提升性能,又彻底解决表格结构错乱问题,是构建可靠数据报表的标准实践。