0

我有 3 张桌子。Apls、船体和 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,但它可能与连接表中没有关联。

这很令人困惑,我知道。

4

2 回答 2

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

于 2009-06-29T22:32:52.353 回答
0

假设您已将表数据提取到一组数组中:

<?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>
于 2009-06-25T13:54:01.220 回答