0

I have all the data in one table in database and I need to display it like in the picture given (example made in excel). The table in database has all the students and their mentors (named profesors in the picture). So,I have to display every mentor and students they are mentoring, but like in the example.enter image description here

Sphere
  • 21
  • 1
  • 5
  • 1
    What you want isn't a table, it'd be a series of lists. – castis May 10 '15 at 19:41
  • You have to determine the requirement. Does it regards, Database, PHP looping for the data, or HTML?! In addition, what do you have tried? – SaidbakR May 10 '15 at 22:45

2 Answers2

0

Unfortunately you don't explain how is data layouted in database, so I need to guess and create example based on fiction.

If you have data in following layout:

professor:            professor_id | name
student:              student_id   | name
professor_x_student:  professor_id | student_id

... then you'd first create 2-dimensional array in PHP (readable but untested pseudo-spaghetti code follows, use your favorite dialect / template / code style):

$resultarray = array();
$sth = query("select p.professor_id, s.student_id, 
  p.name professor_name, s.name student_name from professor p
  inner join professor_x_student pxs on p.professor_id = pxs.professor_id
  inner join student s on pxs.student_id = s.student_id");

$maxstudents = 0;
while ($row = $sth->fetch_assoc()) {
  if (empty($resultarray[$row['professor_id']])) {
    $resultarray[$row['professor_id']] = array('id' => $row['id'], 'name' => $row['professor_name'], 'students' => array());
  }
  $resultarray[$row['professor_id']]['students'][$row['student_id'] = array('id' => $row['student_id'], 'name' => $row['student_name']);
  $maxstudents = count($resultarray[$row['professor_id']]['students']) > $maxstudents ? count($resultarray[$row['professor_id']]['students']) : $maxstudents;
}
$resultarray = array_values($resultarray); // Reset array keys!!
foreach ($resultarray as &$professor) {
  $professor['students'] = array_values($professor['students']); // Reset array keys !!
}

Now, in your template, you just need to iterate over results and draw some nested lists:

echo '<ul class="firstlevel">';
foreach ($resultarray as $professor) {
  echo '<li>'.$professor['name'];
  echo '<ul class="secondlevel">';
  foreach ($professor['students'] as $student) {
    echo '<li>'.$student['name'].'</li>';
  }
  echo '</ul>';
  echo '</li>';
}
echo '</ul>';

In CSS it probably should be something like:

.firstlevel {
  float: left;
}
.secondlevel {
  padding-left: 20px;
}

Updated: In case you are sure you want to use tables, you need some add-on, you need to know what is the max number of students to professor (update in previous fetch code, variable $maxstudents). Also you can't have assoc arrays with this scheme so I changed example on that aspect also.

And then draw table like this:

echo '<table>';
echo '<tr>';
foreach ($resultarray as $professor) {
  echo '<td>'.$professor['name'].'</td>';
}
echo '</tr>';
for ($i = 0; $i < $maxstudents; $i++) {
  echo '<tr>';
  foreach ($resultarray as $professor) {
    if (!empty($professor['students'][$i])) {
      echo '<td>'.$professor['students'][$i]['name'].'</td>'; // echo n-th student
    } else {
      echo '<td>&nbsp;</td>'; // empty cell
  }
  echo '</tr>';
}
echo '</table>';
Kalle Volkov
  • 448
  • 4
  • 8
0
// insert all data in a friendly structured array
// order by here determines horizontal and vertical order. May be other if you want.
$rs = $db->query("select profesor, student from table order by profesor, student");
$out = [];
$counter_by_prof = [];
while($row = $rs->fetchAsoc()) {
    $counter_by_prof[$row['profesor']]++;                                               // works even on not inicialiced values
    $out[$counter_by_prof[$row['profesor']]][$row['profesor']] = $row['student'];       // stack by row by profesor 
}
// output the table from the array
echo '<table>';                                                                         //  /tr /td /th (missing later) are optional
// output header row
echo '<tr>';
foreach($counter_by_prof as $prof=>$tot) echo '<th>'.htmlspecialchars($prof);
// output each row
foreach($out as $row){
    echo '<tr>';
    foreach($counter_by_prof as $prof=>$tot) {
        echo '<td>';
        if(array_key_exists($prof, $row) echo htmlspecialchars($row[$prof]);
        else                             echo '&nbsp;';
    }
}
// bonus line: totals
echo '<tr>';
foreach($counter_by_prof as $prof=>$tot) echo '<td>'.$tot;
echo '</table>';

Side note: if two profesors have the same name, you will need a similar script but ID oriented.

Saic Siquot
  • 6,513
  • 5
  • 34
  • 56
  • did you try this? do you need some extra help? – Saic Siquot May 13 '15 at 13:47
  • I did as you wrote, and it is working (i got the desired pattern on display). But, i get error: "Notice: Undefined index:" for each profesor. Do you know why? Thanks!! :) – Sphere May 18 '15 at 18:17
  • yes, that is becouse your error reporting level includes 'notice' (and my code use undefined indexes over arrays as ceros) there are some ways to [circumvect that](http://stackoverflow.com/questions/4261133/php-notice-undefined-variable-and-notice-undefined-index) – Saic Siquot May 18 '15 at 18:28