0

有点超出我的舒适区,我希望有人能解释实现我需要的最佳方法。

这是一个非常简单的员工考勤系统。

职员表包括职员的姓名。

出勤表包括他们当天工作的日期和班次类型(全班/半班/一天半)。

我现在要做的是创建一个表格,显示两个日期(一个支付期)之间所有员工的出勤情况。

我在想第一列应该是员工姓名,然后后面的列将以两个日期(start_date 和 end_date)之间的每个日期作为标题,然后我想用成员的班次填充表格的其余部分工作人员在特定日期工作。

所以,它看起来像这样:

     Name     |  2013-05-26  |   2013-05-27   |   etc
     -------------------- ---------------------------
     John     |     full     |      half      |
     Mary     |     off      |      full      |
     Peter    |     half     |      full      |

以下查询为我提供了所有数据:

SELECT a.id, first_name, last_name, attDate, staff_id, att, late
FROM staff as a LEFT OUTER JOIN staff_attendance AS b
  ON a.id = b.staff_id 
    AND b.`attDate` >= '2013-05-26' 
    AND  b.`attDate` <= '2013-06-27' 
ORDER BY last_name, attDate;

基本上是:

    id  |   first_name   | last_name |  attDate    | staff_id | att   |  late
    ------------------------------------------------------------------------
    1   |     John       |    smith  | 2013-05-26  |     1    | full  |    0
    1   |     John       |    smith  | 2013-05-27  |     1    | half  |    0
    2   |     Mary       |    Jones  | 2013-05-26  |     2    | off   |    0
    2   |     Mary       |    Jones  | 2013-05-27  |     2    | full  |    0
    3   |     Peter      |    Doe    | 2013-05-26  |     3    | half  |    0
    3   |     Peter      |    Doe    | 2013-05-26  |     3    | full  |    0

如您所见,我拥有所有数据,只是不知道如何将其放入表中。

非常欢迎任何想法或建议。

非常感谢

格雷姆

根据 dev-null-dweller 的建议,我有以下代码:

    $dbh = new PDO("mysql:host=$hostname;dbname=web14-fresh", $username, $password);
    $sql = "SELECT a.id, first_name, last_name, attDate, staff_id, att, late FROM staff as a LEFT OUTER JOIN staff_attendance AS b ON a.id = b.staff_id AND b.`attDate` >= '" .                   $startdate. "' AND  b.`attDate` <= '". $enddate . "' ORDER BY last_name, attDate;";
    $stmt = $dbh->query($sql);

    $dates = array();
    $users = array();

    while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
        $dates[] = $row['attDate'];
        if (!isset($users[$row['id']])) {
            $users[$row['id']] = array(
                'first_name' => $row['first_name'], 
                'last_name' => $row['last_name'],
                'attendance' => array()
            );
        }
        $users[$row['id']]['attendance'][$row['attDate']] = $row['att'];
    }

    $dates = array_unique($dates);
    sort($dates);

    // header
    echo '<table border=1><tr>';
    echo '<td>Name</td>';
    foreach($dates as $d){
        echo '<td>'.$d.'</td>';
    }
    echo '</tr>';

    //data
    foreach($users as $u) {
        echo '<tr><td>'.$u['first_name'].'</td>';
        foreach($dates as $d) {
            if (isset($u['attendance'][$d])) {
                echo '<td>'.$u['attendance'][$d].'</td>';
            } else {
                echo '<td>?</td>';
            }
        }
        //end row
        echo '</tr>';
    }
    echo '</table>';

这似乎并没有填充顶部的所有日期,也看不出原因。这就是我得到的。

    Name        2013-06-26
    Katy    ?   full
    Lauren  ?   full
    Laura   ?   full
    Louise  ?   holiday
    Jade    ?   off

不太确定日期数组没有正确填充:-/

4

4 回答 4

2

一段代码来说明我的评论

$dates = array();
$users = array();

while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
    $dates[] = $row['attDate'];
    if (!isset($users[$row['id']])) {
        $users[$row['id']] = array(
            'first_name' => $row['first_name'], 
            'last_name' => $row['last_name'],
            'attendance' => array()
        );
    }
    $users[$row['id']]['attendance'][$row['attDate']] = $row['att'];
}

$dates = array_unique($dates);
sort($dates);

// header
//echo 'name';
foreach($dates as $d){
    echo $d;
}

//data
foreach($users as $u) {
    //echo $u['first_name'];
    foreach($dates as $d) {
        if (isset($u['attendance'][$d])) {
            echo $u['attendance'][$d];
        } else {
            // for missing records?
        }
    }
    //end row
}
于 2013-06-26T23:29:04.590 回答
1

这是我用于输出 SQL 结果的基本输出循环。它可以从这里使用基于$key值或您拥有的条件格式的条件格式进行扩展。

您还应该对printf()andsprintf()函数友好,因为它们非常有用。

$rs; // assuming this is an indexed array of rows returned from your DB
// ie: $rs[0]['id']

$output = '<table>';

//print header row by iterating through the first result row and printing the keys
$output .= '<tr>';
foreach($rs[0] as $key => $value) {
  $output .= sprintf('<td>%s</td>', $key);
}
$output .= '</tr>';

//now the data rows
foreach($rs as $row) {
  $output .= '<tr>';
  foreach($row as $key => $value) {
    $output .= sprintf('<td>%s</td>', $value);
  }
  $output .= '</tr>';
}

$output .= '</table>';
echo $output;
于 2013-06-26T22:53:35.667 回答
1

简而言之:第一次查询仅创建表头的日期。接下来使用您的查询获取数据以在 html 表中创建所有行。而且您必须记住first_name上一个结果行。如果first_name更改,则在 html 表中开始新行。

伪代码(不完整):

$results = query("SELECT ... only dates");

// ... some html ... opening header row

foreach($results as $date) {
    echo "<td>", $date, "</td>"; 
}

$results = query("SELECT ... your query");
$last__first_name = "";

// ... some html ... closing header row and opening data rows

foreach($results as $row) {

    if( $row->first_name != $last__first_name ) {
        $last__first_name = $row->first_name;
        echo "</tr><tr>"; // create new row in html table
        echo "<td>", $row->first_name, "</td>";
    }

    echo "<td>", $row->att, "</td>"; // next column 
}

// ... some html ... closing table
于 2013-06-26T22:56:55.870 回答
-1

您可以在 HTML 表格中回显结果。首先,您创建标题:

echo '<table>';
echo '<tr><td>Column 1</td><td>Column 2</td><td>Column 3</td>......</tr>';

然后,执行 SQL 查询(SELECT):

$result = mysql_query("SELECT * FROM table ... ...");

在此之后,您可以使用“while”遍历结果:

while ($row = mysql_fetch_array($result ) ) {
echo '<tr><td>'.$row['name_of_column_1_in_db'].'</td><td>'.$row['name_of_column_2_in_db'].'</td> .......... </tr>';
}

然后,关闭表格标签:

echo '</table>';
于 2013-06-26T22:46:26.733 回答