从一对多mysql结果创建多维数组


Create multi dimensional array from one-to-many mysql result

我有三个mysql表:clientscarsinsurance。每个客户可以有多辆车,每辆车可以有多份保险单。以下是我的查询和sqlfiddle:的链接

SELECT
  a.*,
  b.id AS car_id, b.license_number, b.brand, b.model,
  c.id AS insurance_id, c.insurance_company, c.start_date, c.end_date, c.price
FROM clients a
LEFT JOIN cars b ON a.id = b.client_id
LEFT JOIN insurance c ON b.id = c.car_id

http://sqlfiddle.com/#!2/773a5/1

因此,对于两个客户,第一个客户有两辆车和三份保险单,第二个客户没有车也没有保险,查询将返回4行。

我不知道如何循环这个查询以返回以下结构,同时避免重复的客户端条目。

Array
(
  [0] => Array
    (
      [id] => 1
      [first_name] => John
      [last_name] => Smith
      [cars] => Array
        (
          [id] => 1
          [license_number] => 'plate1'
          [brand] => 'BMW'
          [model] => 'E35'
          [insurance] => Array
            (
              [id] => 1
              [start_date] => '2015-02-10'
              [end_date] => '2016-02-10'
              [price] => '100'
            )
            (
              [id] => 2
              [start_date] => '2014-02-10'
              [end_date] => '2015-02-10'
              [price] => '50'
            )
        )
        (
          [id] => 2
          [license_number] => 'plate2'
          [brand] => 'VW'
          [model] => 'Golf'
          [insurance] => Array
            (
              [id] => 3
              [start_date] => '2015-02-10'
              [end_date] => '2016-02-10'
              [price] => '100'
            )
        )
    )
  [1] => Array
    (
      [id] => 1
      [first_name] => John
      [last_name] => Smith
      [cars] => NULL
    )
)

这很容易。它是关于使用一个assoc数组。您可以使用id、car_id和insurance_id作为数组键。

因此,假设您得到的结果是存储在$rows变量中的已提取assoc行。简单的循环是:

$result = array();
foreach($rows as $row) {
    $id    = $row['ID'];
    $carId = $row['CAR_ID'];
    $insId = $row['INSURANCE_ID'];
    $result[$id]['first_name'] = $row['FIRST_NAME'];
    $result[$id]['last_name']  = $row['LAST_NAME'];
    if(!isset($result[$id]['cars'])) {
        $result[$id]['cars'] = array();
    }
    if($carId && !isset($result[$id]['cars'][$carId])) {
        $car = array(
            'id'             => $row['CAR_ID'],
            'license_number' => $row['LICENSE_NUMBER'],
            'brand'          => $row['BRAND'],
            'model'          => $row['MODEL'],
            'insurance'      => array()
        );
        $result[$id]['cars'][$carId] = $car;
    }
    if($insId && isset($result[$id]['cars'][$carId]) && !isset($result[$id]['cars'][$carId]['insurance'][$insId])) {
        $insurance = array(
            'id'         => $row['INSURANCE_ID'],
            'start_date' => $row['START_DATE'],
            'end_date'   => $row['END_DATE'],
            'price'      => $row['PRICE']
        );
        $result[$id]['cars'][$carId]['insurance'][$insId] = $insurance;
    }
}

我不会为您写出所有必要的字段,但它实际上只需要一个fetch循环和一些if()逻辑来构建子数组:

$info = array()
while($row = fetch from db) {
    if(!isset($info[$row['userID']]) {
         $info[$row['userID']] = array(
              'first_name' => $row['first_name'],
              ...
              'cars' => array()
         );
    }
    if (!isset($info[$row['userID']]['cars'][$row['carID']]) {
         etc...
    }
}

对于您放入的每个子数组,您只需要另一个if()测试来初始化该子数组,然后从您获取的$row中填充它。

当您迭代行时,您将自然地构建您的结构。