计算每天有多少员工请假

时间:2021-03-12 13:00:02

标签: php mysql

我正在构建一个应用程序,以在我工作的地方自动分配每个人的休假过程。

能够获得您请求的休假的条件之一是尚未达到我们称为“红线”的条件。红线规定了同一天允许休假的人数,以防止人员短缺。

昨天苦苦思索这个问题,最后想出了如下代码:

// Get data from form fields
$redline = ($_POST["redline"]);    // This sets the Red Line
$rls = strtotime($_POST["rls"]);   // This is the start of the period in which to check
$rle = strtotime($_POST["rle"]);   // This is the end of that period

$redlinereached = 0; // Always starts at 0 and counts +1 if there is a leave 'block' found within the given period

echo "<table class='DataFromDB'>

if (isset($_POST["check"])) {
    $query = mysqli_query($conn,"SELECT * FROM redlinetest ORDER BY staff_id ASC");

    while($row = mysqli_fetch_array($query))
    {
        echo "<tr>";
        echo "<td>" . $row['staff_id'] . "</td>";
        echo "<td>" . $row['name'] . "</td>";
        echo "<td>" . date('d-m-Y',strtotime($row['leave_start'])) . "</td>";
        echo "<td>" . date('d-m-Y',strtotime($row['leave_end'])) . "</td>";

        if ((strtotime($row['leave_start']) >= $rls) && (strtotime($row['leave_end']) <= $rle) or (strtotime($row['leave_end']) >= $rls) && (strtotime($row['leave_start']) <= $rle)) {
            ++$redlinereached;
            echo "<td>Yes</td>";
        } else {
            echo "<td>No</td>";
        }
        echo "</tr>";
    }
echo "</table>";

View a working example

当然,在尝试让它做我想做的事情五个小时后,我对自己很满意,我认为这是检查一段时间内有多少假期......

直到今天早上醒来才意识到,这根本不是我想要的! 我不需要知道一个时期有多少假期,我需要知道每天有多少假期

然后我需要在这段时间内的所有日子里跟踪它,如果到达红线,就‘做点什么’

2 个答案:

答案 0 :(得分:0)

这里有一些伪代码可以为您指明正确的方向。我没有时间测试它,所以你必须自己解决其余的问题。

$start = new DateTime($_POST['rls']);
$end = new DateTime($_POST['rle']);
$interval = new DateInterval('P1D');
$range = new DatePeriod($start->modify('-1 day'), $interval, $end->modify('+1 day'));

foreach ($range as $date) {
    $result = $db->query('select count(*) from redlinetest where leave_start >= $date && leave_end <= $date');
    $row = $result->fetch_row();
    
    if ($row[0] >= $_POST['redline']) {
        // redline reached
    }
}

答案 1 :(得分:0)

你的方法是错误的。您尝试从“redlinetest”读取的数据是已保存在数据库其他位置的数据的表示。除非“redlinetest”是该数据的视图,否则您不应使用它。它打破了关系数据库设计的基本规则,导致系统即使有效,也难以维护。

在尝试设计程序之前先从一组测试用例开始是一种很好的做法,更不用说实际编写任何代码了。您可能会更快地发现当前方法的问题。

您没有告诉我们源数据是什么样的。如果我使用这个:

create table leave (
user_id INT NOT NULL,
start_time dateime NOT NULL,
end_time datetime NOT NULL,
status ENUM ('requested', 'approved')
)

(但有适当的索引)。

第一步是获取一组我们想要计算 $srch_start 和 $srch_end 之间有多少人休假的时间。实际上,我们只需要知道休假人数变化时的人数,所以我们只需要在那个时候进行统计......

SELECT l1.start_time AS event
FROM leave AS l1
WHERE l1.start_time<$search_end
AND l1.end_time>$search_start
AND l1.status='approved'
UNION
SELECT l2.end_time 
FROM leave AS l2
WHERE l2.start_time<$search_end
AND l2.end_time>$search_start
AND l2.status='approved'

为简单起见,我将在此处将此查询称为 $EVENTS。

然后,您可以随时通过...来衡量休假人数。

SELECT event.event AS at_time, COUNT(DISTINCT l.user_id), GROUP_CONCAT(l.user_id)
FROM leave AS l,
($EVENTS) AS event
WHERE l.start_time<=event.event
AND l.end_time>=event.event
AND l.status='approved'
GROUP BY event.event
ORDER BY COUNT(DISTINCT l.user_id) DESC

(这些代码都没有经过测试,我是随意写的 - 但希望你能明白)

尽管我在这里....这是大规模运行的相当昂贵的查询。可以使用地理空间索引构建更有效的解决方案,但这是一个更长的故事。