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

如何将SQL子查询结果整合为客户关联销售记录的主数组

问题

我在SQL数据库中有两张表:

  • booking表:存储客户详情
  • booking_line表:存储客户的购买产品历史

我希望生成一个按客户维度的嵌套数组,每个客户条目下包含其所有购买详情(命名为Sale的子数组),期望的数组格式如下:

array(
        [0] => array(
                 [id] => 67
                 [name] => Neha
                 [mobile_no] => xxxxxxxxx
                 [gender] => Female
                 [Sale] => Array
                    (
                        [id] => 1
                        [booking_id] => 67
                        [barcode] => 1368
                        [product_name] => Custom Print Mattel Rakhi BE
                        [p_price] => 35
                        [price] => 100
                   )
                [Sale] => Array
                    (
                        [id] => 2
                        [booking_id] => 67
                        [barcode] => 1368
                        [product_name] => Custom Print Mattel Rakhi BE
                        [p_price] => 35
                        [price] => 100
                   )
         )
       [1] => array(
                     [id] => 68
                     [name] => Nehaxx
                     [mobile_no] => xxxxxxxxx
                     [gender] => Female
             )
)

但目前得到的输出格式不符合预期,客户和购买记录是平级的数组元素:

array(
        [0] => array(
                 [id] => 67
                 [name] => Neha
                 [mobile_no] => xxxxxxxxx
                 [gender] => Female
         )
        [1] => array(
           [Sale] => Array
                (
                    [id] => 1
                    [booking_id] => 67
                    [barcode] => 1368
                    [product_name] => Custom Print Mattel Rakhi BE
                    [p_price] => 35
                    [price] => 100
               )
         )
        [2] => array(
                 [id] => 68
                 [name] => Nehaxx
                 [mobile_no] => xxxxxxxxx
                 [gender] => Female
         )
         [3] => array(
           [Sale] => Array
                (
                    [id] => 1
                    [booking_id] => 67
                    [barcode] => 1368
                    [product_name] => Custom Print Mattel Rakhi BE
                    [p_price] => 35
                    [price] => 100
               )
         )
)

现有PHP代码如下:

$sqlA = "SELECT * FROM booking";
$resultA = $conn->query($sqlA);
$dataA = array();

while($rowA = $resultA->fetch_assoc()) {
    $sql = "SELECT * FROM booking_line WHERE booking_id=".$rowA["id"]."";
    $result = $conn->query($sql);
    $dataA[] = $rowA;
    
    while($row = $result->fetch_assoc()) {   
        $dataA[] = array("Sale" => $row);
    }
}
print_r($dataA);
解决方案

原代码的问题是把客户数据和购买记录分别追加到了$dataA的顶层,没有将购买记录嵌套到客户数组内部。同时要注意:PHP数组不允许重复键名,原期望输出中同一个客户下的多个Sale键会被覆盖,所以需要把Sale设为索引数组来存储多条购买记录。

修改后的基础版代码

$sqlA = "SELECT * FROM booking";
$resultA = $conn->query($sqlA);
$dataA = array();

while($rowA = $resultA->fetch_assoc()) {
    // 初始化客户数组,包含基础信息
    $customer = $rowA;
    // 初始化Sale子数组,用来存放当前客户的所有购买记录
    $customer['Sale'] = array();
    
    $sql = "SELECT * FROM booking_line WHERE booking_id=".$rowA["id"]."";
    $result = $conn->query($sql);
    
    while($row = $result->fetch_assoc()) {   
        // 将每条购买记录追加到客户的Sale子数组中
        $customer['Sale'][] = $row;
    }
    
    // 将完整的客户数组追加到结果数组
    $dataA[] = $customer;
}
print_r($dataA);

修改后生成的数组结构:

array(
    [0] => array(
        [id] => 67
        [name] => Neha
        [mobile_no] => xxxxxxxxx
        [gender] => Female
        [Sale] => Array(
            [0] => Array(
                [id] => 1
                [booking_id] => 67
                [barcode] => 1368
                [product_name] => Custom Print Mattel Rakhi BE
                [p_price] => 35
                [price] => 100
            ),
            [1] => Array(
                [id] => 2
                [booking_id] => 67
                [barcode] => 1368
                [product_name] => Custom Print Mattel Rakhi BE
                [p_price] => 35
                [price] => 100
            )
        )
    ),
    [1] => array(
        [id] => 68
        [name] => Nehaxx
        [mobile_no] => xxxxxxxxx
        [gender] => Female
        [Sale] => Array() // 无购买记录时为空数组
    )
)

性能优化版(解决N+1查询问题)

原代码每个客户都执行一次查询,会导致性能问题,建议用LEFT JOIN一次性获取所有数据,再在PHP中分组:

// 用LEFT JOIN一次性获取客户及对应购买记录
$sql = "SELECT b.*, bl.id AS bl_id, bl.booking_id, bl.barcode, bl.product_name, bl.p_price, bl.price 
        FROM booking b 
        LEFT JOIN booking_line bl ON b.id = bl.booking_id";
$result = $conn->query($sql);

$dataA = array();
while($row = $result->fetch_assoc()) {
    $bookingId = $row['id'];
    // 如果客户未加入结果数组,先初始化基础信息和Sale子数组
    if(!isset($dataA[$bookingId])) {
        $dataA[$bookingId] = array(
            'id' => $row['id'],
            'name' => $row['name'],
            'mobile_no' => $row['mobile_no'],
            'gender' => $row['gender'],
            'Sale' => array()
        );
    }
    // 仅当存在购买记录时,添加到Sale数组
    if(!empty($row['bl_id'])) {
        $dataA[$bookingId]['Sale'][] = array(
            'id' => $row['bl_id'],
            'booking_id' => $row['booking_id'],
            'barcode' => $row['barcode'],
            'product_name' => $row['product_name'],
            'p_price' => $row['p_price'],
            'price' => $row['price']
        );
    }
}
// 将关联数组转为索引数组
$dataA = array_values($dataA);
print_r($dataA);

内容的提问来源于stack exchange,提问作者Abhinav Goutam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 10:55:26