【问题标题】:MySQL JOIN to arrange results for multiple HTML tables in PHPMySQL JOIN 在 PHP 中为多个 HTML 表排列结果
【发布时间】:2016-10-18 16:25:26
【问题描述】:

我有一个名为“问题”的 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>

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

【问题讨论】:

    标签: php html mysql join


    【解决方案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 来获取 (type,model) 和 (year) 的每个组合。然后我使用 WHERE NOT EXISTS 来查找原始表中不存在的那些组合(“问题”)。接下来,我将原始表中不存在的那些组合(具有 flag='.')与原始表中存在 确实 的组合(具有 flag='Y')结合起来.最后,我按 2010 年到 2017 年的日期范围进行过滤。

    【讨论】:

      【解决方案2】:

      您绝对可以从 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; ?>
      

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

      【讨论】:

      • 谢谢。我真的很想知道一个纯 SQL 的解决方案,所以如果它涉及到你,请告诉我。
      • 仅供参考,我刚刚添加了一个纯 SQL 解决方案。
      【解决方案3】:

      您可以运行如下查询:

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

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

      【讨论】:

      • 这样做的主要问题是,我不知道将哪些“年份”放入表格中,因为对于每种“类型”,每年都不会有问题。
      • 您不想列出所有年份吗?用句号表示当年没有问题? (就像您在上面的 Van 表中显示 2016 年没有问题一样)
      • 是的,我愿意。而且按照你建议的方法,我怎么知道这些年的名单?
      • 您是否有想要显示数据的年份范围?例如,从现在到 10 年前?)
      • 是的,会有一个开始年份和结束年份(只会查询总年份的一个子集)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-22
      • 1970-01-01
      • 1970-01-01
      • 2012-09-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多