php - 如何将mysql表行显示为列

标签 php mysql

我有两个表,resultgp

结果表中我有这样的内容:

|id||student_id   ||course_code||grade||session  ||level||semester|
|1 ||TR/2213234561||MAT111     ||A    ||2009/2010||100  ||first   |
|2 ||TR/2213234561||MAT112     ||B    ||2009/2010||100  ||first   |
|3 ||TR/2213234561||MAT113     ||C    ||2009/2010||100  ||first   |
|4 ||TR/2213234567||MAT111     ||D    ||2009/2010||200  ||first   |
|5 ||TR/2213234567||MAT112     ||C    ||2009/2010||200  ||first   |
|6 ||TR/2213234567||MAT113     ||C    ||2009/2010||200  ||first   |

然后gp

|id||student_id   ||session  ||level||semester||gp |
|1 ||TR/2213234561||2009/2010||100  ||first   ||4.2|
|2 ||TR/2213234567||2009/2010||100  ||first   ||3.5|
|3 ||TR/2213234561||2010/2011||200  ||first   ||4.2|
|4 ||TR/2213234567||2010/2011||200  ||first   ||3.5|

我想要的是这样的:

|Matriculation||MAT111||MAT112||MAT113||MAT114||GP |
|TR/2213234561||A     ||B     ||D     ||C     ||4.2|
|TR/2213234567||C     ||D     ||E     ||F     ||3.5|

类(class)代码不是恒定的 - 它取决于学生注册的类(class)

我已经这样做了:

<?php
$rst1 = mysql_query("select distinct course_code from result ", $conn);
echo "<table callspacing='4'>";
echo "<tr>";
echo "<td> Matriculation Number </td>";

$c_code = array();
while ($row = mysql_fetch_array($rst1))
{
    $c_code[] = $row['course_code'];
}

foreach($c_code as $c_code)
{
    echo "<td>" .$c_code. "</td>";
}

$sql ="SELECT result.student_id,
       MAX(CASE WHEN course_code = ' $c_code' THEN grade END)  $c_code,
       gp.CTC 
       FROM result 
       JOIN gp  
       ON gp.student_id = result.student_id
       GROUP
       BY student_id";

echo "<td> GP</td>";                         
$rst = mysql_query("$sql",$conn) or die(mysql_error());

while ($row = mysql_fetch_array($rst))
{
    echo "</tr>";
    echo "<tr>";
    echo "<td>" .$row['student_id']. "</td>";
    echo "<td>"  .$row[$c_code]. "</td>";
}

echo "<td>"  .$row[$c_code]. "</td>";
echo "<td>" .$row['CTC']. "</td>";

echo"</tr>";
echo "</table>";
?>

第一个查询是获取类(class)代码,因为类(class)不是常量。

使用该代码,我得到了这样的结果:

|Matriculation||MAT111||MAT112||MAT113||MAT114||GP|
|TR/2213234561|
|TR/2213234567|

但我想要

|Matriculation||MAT111||MAT112||MAT113||MAT114||GP |
|TR/2213234561||A     ||B     ||D     ||C     ||4.2|
|TR/2213234567||C     ||D     ||E     ||F     ||3.5|

任何建议或指导都将受到高度赞赏。

最佳答案

您想要做的事情被称为“旋转”数据,其他一些 RDBMS 对此有 native 支持,但 MySQL 没有(根据设计,因为开发人员认为此类操作属于表示层)。

但是,您有几个选择:

  1. 构造一个相当糟糕的 MySQL 查询来手动执行旋转操作:

    SELECT student_id AS Matriculation, MAT111, MAT112, gp AS GP
      FROM gp
      NATURAL JOIN (
        SELECT student_id, grade AS MAT111
        FROM result
        WHERE course_code = 'MAT111'
      ) AS tMAT111
      NATURAL JOIN (
        SELECT student_id, grade AS MAT112
        FROM result
        WHERE course_code = 'MAT112'
      ) AS tMAT112
      -- etc.
    WHERE level = @level AND semester = @semester
    

    如果您选择走这条路,您可以通过使用 PHP 中的循环构造或 MySQL 中的预准备语句自动生成此查询,从而使您的生活稍微轻松一些。

    这是在 PHP 中执行此操作的一种方法:

    1. 获取类(class)列表:

      $dbh = new PDO('mysql:dbname=testdb;host=127.0.0.1', $user, $password);
      $qry = $dbh->query("SELECT DISTINCT course_code FROM result [WHERE ...]");
      $courses = $qry->fetchAll(PDO::FETCH_COLUMN, 0);
      
    2. 循环结果,构建上述 SQL:

      mb_regex_encoding($charset);
      
      $columns = mb_ereg_replace('`', '``', $courses);
      $sql = "
      SELECT student_id AS Matriculation, `".implode("`,`", $columns)."`, gp AS GP
        FROM gp";
      
      foreach ($columns as $column) $sql .= "
        NATURAL JOIN (
          SELECT student_id, grade AS `$column`
          FROM result
          WHERE course_code = ?
        ) AS `t$column`";
      
      $sql .= "
      WHERE level = ? AND semester = ?";
      
    3. 执行 SQL,传入类(class)数组作为参数:

      $qry = $dbh->prepare($sql);
      
      $params = $courses;
      array_push($params, $level, $semester);
      $qry->execute($params);
      
    4. 输出结果:

      echo "<table>";
      
      echo "<tr>";
      for ($i = 0; $i < $qry->columnCount(); $i++) {
        $meta = $qry->getcolumnMeta($i);
        echo "<th scope='col'>" . htmlentities($meta['name']) . "</th>";
      }
      echo "</tr>";
      
      while ($row = $qry->fetch(PDO::FETCH_NUM)) {
        echo "<tr>";
        foreach ($row as $field) echo "<td>" . htmlentities($field) . "</td>"
        echo "</tr>";
      }
      
      echo "</table>";
      
  2. 将上述操作作为一次性操作进行,以便更改 MySQL 数据库的结构以更准确地反射(reflect)所需的布局(表转换后很容易,但可能会影响数据库的其他使用):

    CREATE TABLE StudentGrades (PRIMARY KEY('Matriculation'))
    SELECT student_id AS Matriculation, MAT111, MAT112, gp AS GP
      -- etc. as above
    

    或者,您可以创建 VIEW这是一种基于基础表以这种方式构建的“虚拟表”。

  3. 在 PHP 中手动透视数据(相对繁琐)。

关于php - 如何将mysql表行显示为列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10366023/

相关文章:

mysql - 如何将columnHeaders更改为fieldValues?

php - 将文本区域按行转换为数组,然后使用 Jquery 将其附加到 div?

php - $.ajax 大文件上传超时

php - 删除 phpmyadmin 上的外键表?不能删除索引 : needed in foreign key constraint

javascript - 依赖下拉列表生成

php - 如何在 laravel 5.2 迁移中删除包含外键的组合键

MySQL为每个分组的列值选择一个随机行

php - 将 mysql 的结果放在同一行

php - MySQL 按两列排序

Java JPA - 内部联接查询不起作用