Цикл по многомерному массиву для отображения сетки в PHP - PullRequest
0 голосов
/ 25 июня 2009

у меня 3 таблицы. Apls, Hulls и AplsHulls.

Apls состоит из идентификатора, имени, даты Корпус состоит из идентификатора, имя_производства AplsHulls является таблицей соединений и состоит из id, apl_id, hull_id, status.

Не каждый Халл связан с каждым Apl. Те, которые находятся в таблице соединения со статусом (отправлено, в производстве и т. Д.)

Мне нужно отобразить отчет в таблице / сетке со следующими заголовками столбцов: Apl Name, Apl_Date, а затем имена производственной оболочки в качестве оставшихся заголовков столбцов. (если корпус 7 не входит в набор результатов, он даже не получает столбец.

Для данных мне нужно указать имя apl, дату apl, затем выполнить цикл по оставшимся столбцам и заполнить статус записей в таблице соединений. Если apl и hull не связаны в таблице соединений, просто заполните ячейку "NA".

Я пробовал эту кучу разных способов, и в настоящее время я могу получить динамический список заголовков столбцов для оболочек, мне кажется, что я никогда не смогу заставить данные циклически проходить правильно.

Sample Data:

Apls Table

Id: 1, Name: X1-0000, Date: 1/1/2009
Id: 2, Name: BG-5480, Date: 2/22/2009
Id: 3, Name: HG-0000, Date: 2/27/2009

Hulls Table

Id: 1, Production_name: ProdA
Id: 2, Production_name: ProdB
Id: 3, Production_name: ProdC
Id: 4, Production_name: ProdD

AplsHulls Table

Id: 1, Apl_id: 1, Hull_id: 1, Status:Delivered
Id: 2, Apl_id: 1, Hull_id: 3, Status:Ordered
Id: 3, Apl_id: 2, Hull_id: 4, Status:Delivered

Мне нужно, чтобы таблица отображалась следующим образом:

  APL   |     Date     |    ProdA    |   ProdC   | ProdD
X1-0000 |  01/01/2009  |  Delivered  |  Ordered  | NA 
BG-5480 |  02/22/2009  |     NA      |     NA    | Delivered

Обратите внимание, что заголовки столбцов игнорируют ProdB, поскольку этой записи вообще не было в таблице соединений. Также он заполняет NA для столбцов, которые находятся в таблице соединения, но может не иметь связи с в таблице соединения.

Это очень запутанно, я знаю.

Ответы [ 2 ]

1 голос
/ 30 июня 2009

Вы можете получить список корпусов, которые вам интересны, с помощью запроса:

select h.id, pname from hulls h join aplshulls on (h.id=hull_id)

Вы можете (и, вероятно, должны) прекратить чтение этого ответа сейчас и просто использовать, чтобы получить столбцы, которые вам интересны, а затем выяснить, как поместить данные, которые у вас есть, в таблицу.

Но как только у вас есть этот список оболочек, который вам небезразличен, ваша программа может написать какой-то злой sql для построения результата для вас. В приведенном ниже коде предполагается, что ваша библиотека БД возвращает массив строк для вашего SQL-запроса.

$hulls = query("select h.id, pname from hulls h join aplshulls on (h.id=hull_id)");
/* This should give a result like:
 * $hulls = array(array('id'=>1,'pname'=>'proda'),
 *                array('id'=>3,'pname'=>'prodc'),
 *                array('id'=>4,'pname'=>'prodd'));
 */

$sql = "select name, mdate";
foreach ($hulls as $row) {
    $sql .= ", ifnull({$row['pname']},'NA') {$row['pname']}";
}
$sql .= " from apls ";

foreach ($hulls as $row) {
    $sql .= " left join (select apl_id, status as {$row['pname']} from hulls h \join aplshulls ah on (h.id=hull_id) where pname='{$row['pname']}') as {$row['pn\ame']} on ({$row['pname']}.apl_id=apls.id)";
}
$sql .= " where apls.id in (select distinct apl_id from aplshulls)";

$result = query($sql);
foreach ($result as $row) {
  print "<tr>";
  foreach ($row as $value) {
    print "<td>$value</td>";
  }
  print "</tr>\n";
}

Замените вызовы на запрос методами запроса к базе данных.

Полученный sql:

select name, date,
       ifnull(proda,'NA') proda, ifnull(prodc,'NA') prodc, ifnull(prodd,'NA') prodd
from apls
     left join (select apl_id, status as proda
                from hulls h join aplshulls ah on (h.id=hull_id)
                where pname='proda') as proda on (proda.apl_id=apls.id)
     left join (select apl_id, status as prodc
                from hulls h join aplshulls ah on (h.id=hull_id)
                where pname='prodc') as prodc on (prodc.apl_id=apls.id)
     left join (select apl_id, status as prodd
                from hulls h join aplshulls ah on (h.id=hull_id)
                where pname='prodd') as prodd on (prodd.apl_id=apls.id)
where
  apls.id in (select distinct apl_id from aplshulls);

Возможно, есть лучший способ построить запрос, но это должно сработать. Вероятно, он сломается, если количество корпусов будет очень большим. Или если какая-либо из задействованных таблиц очень большая. Если названия ваших продуктов не разрешены в SQL, вам нужно сопоставить их с чем-то другим.

0 голосов
/ 25 июня 2009

Предполагая, что вы извлекли данные таблицы в набор массивов:

<?php
    $aplToHullMap = array();

    foreach( $AplsHulls as $row )
    {
        $aplID = $row[ 'apl_id' ];
        $hullID = $row[ 'hull_id' ];
        $status = $row[ 'status' ];

        if( isset( $aplToHullMap[ $aplID ] ) )
            $aplToHullMap[ $aplID ][ $hullID ] = $status;
        else
            $aplToHullMap[ $aplID ] = array( $hullID => $status );
    }
?>
<table>
  <tr>
    <th>Apl Name</th>
    <th>Apl Date</th>
<?php
    foreach( $Hulls as $row )
        echo( "<th>" . $row[ 'production_name' ] . "</th>\r\n" );
?>
  </tr>
<?php
    foreach( $Apls as $row )
    {
?>
  <tr>
    <td><?php echo( $row[ 'name' ] ); ?></td>
    <td><?php echo( $row[ 'date' ] ); ?></td>
    <?php
        $map = $aplToHullMap[ $row[ 'id' ] ];

        foreach( $Hulls as $hull )
        {
            if( isset( $map[ $hull[ 'id' ] ] ) )
                $status = $map[ $hull[ 'id' ] ];
            else
                $status = 'NA';

            echo( "<td>" . $status . "</td>\r\n" );
        }
    ?>
  </tr>
<?php
    }
?>
</table>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...