You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用mysqli与PHP实现动态数据透视表遇到问题求助

解决PHP + mysqli实现动态数据透视表的问题

我明白你现在的困境——MySQL里能跑的动态透视表SQL,放到PHP里用多查询就出问题,静态版本没问题但动态的卡壳了。咱们一步步拆解问题,修复代码:

核心问题分析

你的代码主要有两个关键问题:

  • 多查询的结果集处理错误:mysqli_multi_query执行后,前面的SET、SELECT INTO、PREPARE语句都不会返回数据行,只有EXECUTE stmt才会返回最终的透视表结果。你直接用第一个结果集去判断行数,自然拿不到数据。
  • 字符串转义和调试缺失:SQL语句里的单引号嵌套容易出错,而且没有错误捕获,导致你不知道到底哪一步失败了。

修正后的代码

下面是调整后的完整代码,我加了详细的注释和错误处理:

function get_all_records() {
    $conn = getdb();
    // 使用HEREDOC编写SQL,避免单引号转义混乱
    $Sql = <<<SQL
SET @sql = NULL;
SELECT GROUP_CONCAT(DISTINCT CONCAT(
    'MAX(IF(suo.date = ''', date, ''', suo.units_ordered, 0)) AS ', CONCAT('`',date,'`')
)) INTO @sql FROM tbl_sku_units_order;
SET @sql = CONCAT('SELECT ls.sku AS list_sku, COALESCE(MIN(suo.sku), ''NotSold'' ) AS sold_sku, ', @sql, ' , COALESCE( SUM(suo.units_ordered), 0 ) AS total_sold FROM tbl_list_sku AS ls LEFT JOIN tbl_sku_units_order AS suo ON suo.sku = ls.sku GROUP BY ls.sku ORDER BY total_sold DESC');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SQL;

    // 执行多查询
    if (mysqli_multi_query($conn, $Sql)) {
        $result = null;
        // 遍历所有结果集,找到EXECUTE返回的那个
        do {
            if ($currentResult = mysqli_store_result($conn)) {
                $result = $currentResult;
                mysqli_free_result($currentResult);
            }
        } while (mysqli_next_result($conn));

        if ($result && mysqli_num_rows($result) > 0) {
            // 获取表头(动态生成的日期字段)
            $fields = mysqli_fetch_fields($result);
            echo "<table><thead><tr>";
            foreach ($fields as $field) {
                echo "<th>" . htmlspecialchars($field->name) . "</th>";
            }
            echo "</tr></thead><tbody>";

            // 输出数据行
            while ($row = mysqli_fetch_assoc($result)) {
                echo "<tr>";
                foreach ($row as $value) {
                    echo "<td>" . htmlspecialchars($value) . "</td>";
                }
                echo "</tr>";
            }
            echo "</tbody></table></div>";
        } else {
            echo "<p class='text-center'>You have no recent QTY Daily Inventory</p>";
        }
    } else {
        // 调试用:输出SQL错误
        echo "<p class='text-center'>SQL Error: " . mysqli_error($conn) . "</p>";
    }

    mysqli_close($conn);
}

关键改进点

  1. 结果集遍历:通过do-while循环调用mysqli_next_result,跳过前面无数据的结果集,只保留EXECUTE返回的最终数据。
  2. HEREDOC语法:用HEREDOC写SQL,避免了单引号嵌套的转义问题,代码可读性更强。
  3. 动态表头和数据输出:不再硬编码字段名,而是通过mysqli_fetch_fields获取动态生成的日期字段,确保所有列都能正确显示。
  4. 错误处理:添加了mysqli_error输出,方便你调试时查看具体的SQL错误。
  5. 安全处理:用htmlspecialchars转义输出内容,防止XSS攻击。

额外调试建议

如果还是有问题,可以先把生成的@sql变量打印出来,看看最终拼接的SQL是否正确:

// 在EXECUTE stmt之前添加这行SQL
$Sql .= "SELECT @sql;";

然后在遍历结果集的时候,把@sql的内容输出,复制到MySQL Workbench里执行,验证SQL本身是否正确。

内容的提问来源于stack exchange,提问作者Steven Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:40:50