sql >> データベース >  >> RDS >> Mysql

mysqlテーブルの行を列として表示するにはどうすればよいですか

    あなたがやりたいことは、データの「ピボット」と呼ばれ、他のRDBMSがネイティブでサポートしているものですが、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つの方法は次のとおりです。

      1. コースのリストを取得する:

        $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を実行し、コースの配列をパラメーターとして渡します。

        $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. 上記を1回限りの操作として実行し、MySQLデータベースの構造を変更して、この目的のレイアウトをより厳密に反映させます(テーブルが変換されると簡単ですが、データベースの他の用途に影響を与える可能性があります):

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

      または、 VIEW> これは、基になるテーブルに基づいてこのように構造化された一種の「仮想テーブル」です。

    3. PHPでデータを手動でピボットします(比較的面倒です)。




    1. MySQLは外部キー制約を追加できません

    2. MySqlは列をauto_incrementにすることができません

    3. すべてのテキストベースのフィールドに汎用varchar(255)を使用することに不利な点はありますか?

    4. 1つの行で複数の列のAVGを選択するにはどうすればよいですか