У меня есть две таблицы, result
и gp
.
В таблице result
меня есть что-то вроде этого:
|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
table
|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|
Код курса не является постоянным – это зависит от курса, зарегистрированного учащимися
Я сделал это:
<?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>"; ?>
Первый запрос заключался в том, чтобы получить код курса, поскольку курсы не являются константами.
с этим кодом я получил что-то вроде этого:
|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|
Любое предложение или руководство будут высоко оценены.
То, что вы хотите сделать, известно как «поворот» ваших данных и является тем, для чего у некоторых других СУБД есть встроенная поддержка, но MySQL не делает (по дизайну, поскольку разработчики считают, что такие манипуляции относятся к уровню представления).
Однако у вас есть несколько вариантов:
Постройте довольно ужасный запрос 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:
Получить список курсов:
$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);
Прокрутите результаты, построив указанный выше 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 = ?";
Выполните SQL, пройдя в массиве курсов в качестве параметров:
$qry = $dbh->prepare($sql); $params = $courses; array_push($params, $level, $semester); $qry->execute($params);
Выведите результаты:
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>";
Выполните описанную выше процедуру как одноразовую операцию, чтобы изменить структуру вашей базы данных MySQL, чтобы более точно отразить этот желаемый макет (легко, как только таблица будет преобразована, но может повлиять на другие виды использования базы данных):
CREATE TABLE StudentGrades (PRIMARY KEY('Matriculation')) SELECT student_id AS Matriculation, MAT111, MAT112, gp AS GP -- etc. as above
Кроме того, вы можете создать VIEW
который является своего рода «виртуальной таблицей», структурированной таким образом на основе базовой таблицы.
Развертывание данных вручную на PHP (относительно утомительно).