【问题标题】:Loop through multi dimension array to show grid in PHP循环遍历多维数组以在 PHP 中显示网格
【发布时间】:2009-06-25 13:35:16
【问题描述】:

我有 3 张桌子。 Apls、Hulls 和 AplsHulls。

Apls 由 id、name、date 组成 Hulls 由 id、production_name 组成 AplsHulls是一个连接表,由id、apl_id、hull_id、status组成。

并非每个船体都与每个 Apl 相关联。连接表中的状态(已发货、生产中等)

我需要在具有以下列标题的表格/网格中显示报告:Apl 名称、Apl_Date 然后船体生产名称作为剩余的列标题。 (如果 hull 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,但它可能与连接表中没有关联。

这很令人困惑,我知道。

【问题讨论】:

  • 一些示例代码可能会有所帮助,并且可能会从您的表中采样数据
  • 请提供有关您的数据的更多信息。它是像您的标题所暗示的那样在数组中,还是像问题本身所暗示的那样在数据库表中?一个示例表而不是冗长的描述也会有所帮助。
  • 样本数据:Apls 表 ID:1,名称:X1-0000,日期:2009 年 1 月 1 日 ID:2,名称:BG-5480,日期:2009 年 2 月 22 日 ID:3 ,名称:HG-0000,日期:2/27/2009 Hulls 表 ID:1,Production_name:ProdA Id:2,Production_name:ProdB Id:3,Production_name:ProdC Id:4,Production_name:ProdD AplsHulls 表 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 |日期 |产品 |产品 |产品 X1-0000 | 2009 年 1 月 1 日 |已交付 |已订购 | NA BG-5480 | 2009 年 2 月 22 日 |不适用 |不适用 |已交付 请注意,列标题忽略 ProdB,因为该记录根本不在连接表中。它还为连接表中的列填充 NA,但它可能与连接表中没有关联。这很令人困惑,我知道。
  • 您应该编辑问题并在信息前面放置四个空格,这将形成一个代码块(如下面发布的答案)并保留您的格式。

标签: php loops multidimensional-array


【解决方案1】:

您可以通过这样的查询获得您关心的船体列表:

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 中不合法,您需要将它们映射到其他名称。

【讨论】:

    【解决方案2】:

    假设您已将表格数据拉入一组数组中:

    <?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>
    

    【讨论】:

      猜你喜欢
      • 2012-04-21
      • 2011-01-02
      • 2016-02-16
      • 2021-09-17
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      相关资源
      最近更新 更多