动态HTML表 - 更新单元格行

时间:2014-03-12 04:42:53

标签: php mysql

我有一个从数据库动态生成的HTML表。在这个问题Adding rows to a HTML table with dynamic columns中可以看到实现这一目标的解决方案。

enter image description here

这样可以正常工作,除了我想在同一行中指出一个人每周参加的所有会话 - 使用下面的代码,额外的会话出席成为附加到HTML表的另一行。所以我想要的是:

enter image description here

数据库表就像('周','同期''出勤'表)

+---------+-----------+----------+-----------+
| week_pk | week_name | sessions | cohort_fk |
+---------+-----------+----------+-----------+
|       1 | Week 1    |        3 |         1 |
|       2 | Week 2    |        2 |         1 |
|       3 | Week 3    |        1 |         1 |
+---------+-----------+----------+-----------+

+-----------+-------------+-------------+-------------+
| cohort_pk | cohort_name | cohort_code | cohort_year |
+-----------+-------------+-------------+-------------+
|         1 | Some name   | MICR8976    |        2014 |
+-----------+-------------+-------------+-------------+   

+---------------+-----------+-------------+---------+-----------+---------+---------+
| attendance_pk | person_id | given_names | surname | cohort_fk | week_fk | session |
+---------------+-----------+-------------+---------+-----------+---------+---------+
|             1 |    123456 | Bill        | Smith   |         1 |       1 |       2 |
|             2 |    123456 | Bill        | Smith   |         1 |       2 |       2 |
|             3 |    753354 | Fred        | Jones   |         1 |       1 |       1 |
|             4 |    753354 | Fred        | Jones   |         1 |       2 |       1 |
|             5 |    753354 | Fred        | Jones   |         1 |       3 |       1 |
+---------------+-----------+-------------+---------+-----------+---------+---------+

我正在使用的代码:

$cohort = $_POST['cohort'];
$year = $_POST['year'];


$query = "SELECT * FROM cohort, week 
WHERE week.cohort_fk = cohort.cohort_pk 
AND cohort.cohort_year = '$year' 
AND cohort.cohort_pk = '$cohort'
ORDER BY week.week_pk";

$result = mysql_query($query, $connection) or die(mysql_error());

echo "<table width='100%' cellpadding='4' cellspacing='0'  class='attendance_table'>";
echo "<tr><td class='theadings'></td>";
$second_row = "<tr><td class='theadings'></td>";
$totalcolumn = 1;                               
while( $row = mysql_fetch_assoc($result) ){
    $weekname   = $row["week_name"];
    $n_session  = $row["sessions"];
    $weekpk     = $row["week_pk"];              
    $totalcolumn += $n_session;                 
    echo "<td class='theadings' colspan='$n_session'>$weekname</td>";
    for($i=1; $i<=$n_session; $i++){
        $second_row .= "<td class='theadings_lab'>Lab $i</td>";
        $weeksession[$weekpk][$i] = $totalcolumn - $n_session + $i;
    }
}
echo "</tr>";
echo $second_row . "</tr>";


$query = "SELECT * FROM cohort, week, attendance 
WHERE week.cohort_fk = cohort.cohort_pk 
AND attendance.week_fk = week.week_pk
AND attendance.cohort_fk = cohort.cohort_pk
AND cohort.cohort_year = '$year' 
AND cohort.cohort_pk = '$cohort'
ORDER BY attendance.attendance_pk";
$result = mysql_query($query, $connection) or die(mysql_error());
while( $row = mysql_fetch_assoc($result) ){
    $name = $row["given_names"] . " " . $row["surname"];
    $weekpk = $row["week_pk"];
    $sno = $row["session"];
    echo "<tr><td class='tborder_person_left'>$name</td>";
    for($i=2; $i<=$totalcolumn; $i++){      
        if( $weeksession[$weekpk][$sno] == $i )
            echo "<td class='tborder_person_attended'>&#10004</td>";
        else
            echo "<td class='tborder_person'>-</td>";              
    }                                       
    echo "</tr>";
}//end while
echo "</table>";

下面的@Kickstart是表格与您的代码相似的示例。你可以看到例如Melody Chew和Kit Yeng Melody Chew(同一个人)有两个单独的行。唯一标识符必须位于出勤表中存在的person_id上(对于之前未显示此内容的道歉! my BAD 请注意表格右侧的附加列,其中应包含十字形第2周。

enter image description here

2 个答案:

答案 0 :(得分:2)

我个人会经历嵌套数组。

我举个例子。请注意,这只是原则上,因为我没有数据库,我还没有测试过。 :)

1 - &gt;数组$liste_name = array();的语句

2 - &gt;通过以下方式替换您的第二次治疗:

while( $row = mysql_fetch_assoc($result) ){

    $name = $row["given_names"] . " " . $row["surname"];
    $weekpk = $row["week_pk"];
    $sno = $row["session"];
    $person_id = $row["person_id"]; //add person_id


    $liste_name[$person_id] = $name; // to have the last name
    $tab[$person_id][1] = "<td class='tborder_person_left'>$name</td>"; // to have the last name

    for($i=2; $i<=$totalcolumn; $i++){

        if( $weeksession[$weekpk][$sno] == $i )
            $tab[$person_id][$i] = "<td class='tborder_person_attended'>&#10004</td>";              
    }
}//end while

3 - &gt;填空区:

foreach ($liste_name as $person_id => $name){

    $tab2[$person_id][1] = $tab[$person_id][1]; 

    for($i=2; $i<=$totalcolumn; $i++){
        if (!isset($tab[$person_id][$i]) || ($tab[$person_id][$i] != "<td class='tborder_person_attended'>&#10004</td>"))
            $tab[$person_id][$i] = "<td class='tborder_person'>-</td>";
        $tab2[$person_id][$i] = $tab[$person_id][$i]; 
    }
}

4 - &gt;使用数组:

foreach($tab2 as $person_id => $col){
    echo "<tr>";
    foreach ($col as $i => $value){
        echo $value;
    }
    echo "</tr>";
}

echo "</table>";

我尝试使用虚构数据并且可以正常运行。 :)

答案 1 :(得分:2)

我很想使用几个CROSS JOIN来获得会话/周/人的所有可能组合,然后离开加入,以防止出席。

SELECT unique_names.given_names, 
        unique_names.surname,
        week_sessions.week_pk, 
        week_sessions.session,
        attendance.attendance_pk
FROM
(
    SELECT week_pk, sub1.i AS session, week_name, week.cohort_fk, cohort.cohort_year 
    FROM week
    INNER JOIN cohort 
    ON week.cohort_fk = cohort.cohort_pk
    INNER JOIN
    (
        SELECT 1 i UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
    ) sub1
    ON week.sessions >= sub1.i
    WHERE cohort.cohort_year = 2014 
    AND cohort.cohort_pk = 1
) week_sessions
CROSS JOIN
(
    SELECT DISTINCT given_names, surname 
    FROM attendance
) unique_names
LEFT OUTER JOIN attendance
ON week_sessions.week_pk = attendance.week_fk
AND week_sessions.cohort_fk = attendance.cohort_fk
AND week_sessions.session = attendance.session
AND unique_names.given_names = attendance.given_names
AND unique_names.surname = attendance.surname
ORDER BY unique_names.given_names, 
        unique_names.surname,
        week_sessions.week_pk, 
        week_sessions.session

我为此敲了一个SQL小提琴: -

http://www.sqlfiddle.com/#!2/4a388/7

然后你可以轻松地绕过这个(尽管添加标题有点乱 - 以下是没有标题的一半大小)。我已经使用了mysql_ *函数,因为你已经在使用它了。

<?php

$connection = mysql_connect("localhost", "root", "") or die(mysql_error());
mysql_select_db("test_area") or die(mysql_error());

$sql = "SELECT unique_names.person_id,
                unique_names.FullName,
                week_sessions.week_pk, 
                week_sessions.session,
                attendance.attendance_pk
        FROM
        (
            SELECT week_pk, sub1.i AS session, week_name, week.cohort_fk, cohort.cohort_year 
            FROM week
            INNER JOIN cohort 
            ON week.cohort_fk = cohort.cohort_pk
            INNER JOIN
            (
                SELECT 1 i UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
            ) sub1
            ON week.sessions >= sub1.i
            WHERE cohort.cohort_year = 2014 
            AND cohort.cohort_pk = 1
        ) week_sessions
        CROSS JOIN
        (
            SELECT person_id, MAX(CONCAT_WS(' ', given_names, surname)) AS FullName
            FROM attendance
            GROUP BY person_id
        ) unique_names
        LEFT OUTER JOIN attendance
        ON week_sessions.week_pk = attendance.week_fk
        AND week_sessions.cohort_fk = attendance.cohort_fk
        AND week_sessions.session = attendance.session
        AND unique_names.person_id = attendance.person_id
        ORDER BY unique_names.person_id,
                unique_names.FullName,
                week_sessions.week_pk, 
                week_sessions.session";

$result = mysql_query($sql, $connection) or die(mysql_error());
$prev_person_id = 0;
$first = true;
$header = array('Name'=>array('Session'));
$output = array();
while( $row = mysql_fetch_assoc($result) )
{
    if ($prev_person_id != $row['person_id'])
    {
        if ($prev_person_id != 0)
        {
            $first = false;
        }
        $prev_person_id = $row['person_id'];
        $output[$prev_person_id] = array();
    }
    if ($first)
    {
        $header["Week ".$row['week_pk']]["S".$row['session']] = "S".$row['session'];
    }
    $output[$prev_person_id][] = (($row['attendance_pk'] == '') ? '&nbsp;' : 'X');
}

$header1 = '';
$header2 = '';
foreach($header as $key=>$value)
{
    $header1 .= "<td colspan='".count($value)."'>$key</td>\r\n";
    foreach($value as $key1=>$value1)
    {
        $header2 .= "<td>$value1</td>\r\n";
    }
}
echo "<table border='1'>\r\n";
echo "<tr>\r\n$header1</tr>\r\n";
echo "<tr>\r\n$header2</tr>\r\n";

foreach($output as $name=>$value)
{
    echo "<tr><td>$name</td>";
    foreach($value as $key1=>$value1)
    {
        echo "<td>$value1</td>\r\n";
    }
    echo "</tr>";
}

echo "</table>\r\n";

?>