MySQL JOIN在PHP中为多个HTML表排列结果

时间:2016-06-17 00:15:57

标签: php html mysql join

我有一个名为“Problems”的MySQL数据库:

  year  type  model
  ----  ----  -----
  2016  Cars  A
  2016  Cars  B
  2015  Cars  A
  2014  Cars  C
  2015  Vans  D
  2014  Vans  E

对于不同“类型”的车辆,它列出了存在问题的“模型”以及这些模型存在问题的年份。

我需要为每种类型的车辆创建单独的HTML表格。在每个表中,每个模型需要一行,每年需要一列。我将在单元格中使用“Y”来指定问题,并使用句点(“。”)来表示没有问题。

也就是说,我需要创建以下两个HTML表:

汽车的HTML表格:

    2016    2015    2014
A    Y       Y       .
B    Y       .       .
C    .       .       Y

Vans的HTML表格:

    2016    2015    2014
D    .       Y       .
E    .       .       Y

我将在PHP中使用mysqli来查询数据库并构造表。我想我可以为每个表单独查询,但这似乎不是最经济的方法。是否可以执行将返回有序行的查询,以便我基本上可以执行这样的迭代模式?

for type in types:
    // write start of <TABLE>
    for model in models:
        // write start of <TR>
        for year in years:
            // write <TD>
        // write close of <TR>
    //write close of <TABLE>

如果执行许多不同的查询更有意义,请提供建议。

3 个答案:

答案 0 :(得分:1)

你可以运行这样的查询:

SELECT * FROM Problems ORDER BY VehicleType, VehicleModel, VehicleYear;

之后,使用上面显示的逻辑循环结果。查询本身不会将行放在您想要的位置,但您的查询结果将以允许您遍历结果的方式进行排序,因此您布置的逻辑应该可以正常工作。

答案 1 :(得分:1)

你绝对可以从sql中设计一些完全可以做到的东西,我现在无法想到它,但另一种方法是重新组织数组,使其符合该表格的格式。

我想按照格式对它们进行分组。

首先按类型分组,然后按型号分组,然后按年份分组。按顺序排列它们。

$data[type][model][year]

请注意,您在获取时需要重新排列数组。

你可以遵循这个想法。这只会给你一个简单的选择:

$sql = 'SELECT * FROM problems';
$query = $con->query($sql);
while($row = $query->fetch_assoc()) {
    for($i = date('Y'); $i > 2013; $i--) {
        $data[$row['type']][$row['model']][$i][] = ($i == $row['year']) ? 'Y' : '';     }   
}

请注意,Y''只是有价值的占位符,您可以拥有任何类型。

在分组之后,您将以此格式结束,这将更容易在您的标记中回显:

Array
(
    [cars] => Array
        (
            [A] => Array
                (
                    [2016] => 
                    [2015] => Y
                    [2014] => 
                )

            [B] => Array
                (
                    [2016] => Y
                    [2015] => 
                    [2014] => 
                )

            [C] => Array
                (
                    [2016] => 
                    [2015] => 
                    [2014] => Y
                )

        )

    [vans] => Array
        (
            [D] => Array
                (
                    [2016] => 
                    [2015] => Y
                    [2014] => 
                )

            [E] => Array
                (
                    [2016] => 
                    [2015] => 
                    [2014] => Y
                )

        )

)

现在,您只需使用一系列foreach即可。第一个循环转到每个代表type(汽车,面包车等)的表,因为每个表都需要自己的表。

然后是每辆车的车型。最后,哪些年有价值。

<?php foreach($data as $type => $v1) : ?>
    <h4><?php echo $type; ?></h4><!-- clasification -->
    <table id="<?php echo $type; ?>" cellpadding="10">
        <!-- year header -->
        <tr><th></th><?php foreach(array_keys(reset($v1)) as $year) echo "<th>{$year}</th>"; ?></tr>

        <?php foreach($v1 as $model => $v2): ?>
            <tr align="center">
                <td><?php echo $model; ?></td>
                <?php for($i = date('Y'); $i > 2013; $i--): ?>
                    <td><?php echo (!empty(array_filter($v2[$i]))) ? 'Y' : '.'; ?></td>
                <?php endfor; ?>

            </tr>
        <?php endforeach; ?>


    </table>
<?php endforeach; ?>

这将创建一个与上图相似的结构。请注意,您自己需要进行设计。

答案 2 :(得分:1)

在与此挣扎之后,我终于设法提出了一个纯粹的SQL解决方案:

SELECT * FROM
(
    SELECT `type`, `model`, `year`, '.' AS flag
    FROM (
        SELECT * FROM
        (SELECT `type`, `model` FROM Problems GROUP BY `type`, `model`) tt
        CROSS JOIN
        (SELECT DISTINCT `year` FROM Problems) d
          ) x
    WHERE NOT EXISTS (
          SELECT 1
          FROM Problems h
          WHERE x.`year` = h.`year` AND x.`type` = h.`type` AND x.`model` = h.`model`
          )
    UNION
    SELECT `type`, `model`, `year`, 'Y' AS flag
    FROM Problems
    ORDER BY `type`, `model`, `year`
) z
WHERE `year` >= 2010 AND `year` <= 2017

我首先使用CROSS JOIN来获得(类型,模型)和(年)的每个组合。然后我使用WHERE NOT EXISTS来查找原始表中不存在的那些组合(“Problems”)。接下来,我将原始表中不存在的那些组合(具有flag ='。')与原始表中存在 do 的组合(具有flag ='Y')组合在一起。最后,我按照2010年到2017年的日期范围进行过滤。