Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/248.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 难以找到计算员工缺勤天数的解决方案_Php_Function_Laravel - Fatal编程技术网

Php 难以找到计算员工缺勤天数的解决方案

Php 难以找到计算员工缺勤天数的解决方案,php,function,laravel,Php,Function,Laravel,我有四张桌子 tbl\U员工 员工身份证(PK) 职员姓名 创建于 更新地址 tbl\U假日 id(主键) 假日日 描述 待离开 id(主键) 职员身份证(FK) 开始日期 结束日期 没有几天了 tbl\U出席人数 id(主键) 登记入住 退房 检查 迟到 职员身份证(FK) 退出时间 现在我想计算一名员工从加入之日起的缺勤天数。我想删除假日日期和星期六。我想让函数类似于通过两个参数计算缺勤天数函数(开始日期、结束日期)并计算这两天之间缺勤天数。但我没有找到解决方案的起点。因此,任何帮助都将不胜

我有四张桌子

tbl\U员工

员工身份证(PK)

职员姓名

创建于

更新地址

tbl\U假日

id(主键)

假日日

描述

待离开

id(主键)

职员身份证(FK)

开始日期

结束日期

没有几天了

tbl\U出席人数

id(主键)

登记入住

退房

检查

迟到

职员身份证(FK)

退出时间


现在我想计算一名员工从加入之日起的缺勤天数。我想删除假日日期和星期六。我想让函数类似于通过两个参数计算缺勤天数函数(开始日期、结束日期)并计算这两天之间缺勤天数。但我没有找到解决方案的起点。因此,任何帮助都将不胜感激

首先,您的一些日期是“日期”类型,而其他日期必须是“日期时间”类型。这对于连接很重要:在比较“date”和“datetime”类型的字段时,可能需要将MySQL date()函数应用于“datetime”字段以启用直接比较。(我假设您使用的是MySQL:在日历日期类型、范围和函数方面,SQL系统之间存在一些小的差异:您也需要注意日期计算函数结果的范围,因为这些有时可能有实际限制。)以下示例使用子查询:MySQL的某些版本可能比其他版本更好地支持这些子查询

我以前创建过此类查询,我认为基本上有两种方法可以解决此问题:

  • 创建自业务开始以来所有工作日的查找表;左连接此(其中条件为:右侧为空)和tbl_。这种方法设计简单,但在计算效率方面非常次优,并且没有必要采用这种方法
  • 评估员工工作的总日历日数(tbl_出勤率)。通过评估日期范围的总和/差异,评估员工本应工作的日历天数。您将使用MySQL函数,如:IF()、DATEDIFF()、DATE()、WEEKDAY()——雇佣合同的形式将决定您的报告应采用何种形式,这将决定SQL查询的确切形式
  • 按日期列出法定公共假日是有意义的(政府几乎可以随时创建/更改/取消法定公共假日);但另一方面,要按日期范围列出休假期间和出勤期间。因此,我可以看到您的表/字段设计背后的基本原理(看起来不错);但您应该知道,您的解决方案(非常恰当)包含设计方法1的元素,也包含设计方法2的元素

    在设计/测试SQL查询之前,您需要制定一些基本规则,这些规则将由验证规则/查询/触发器支持: 此外,验证/确保结束日期不/不能先于开始日期(这将违反以下设计假设):为了支持/简化此设计假设,我将假设您的所有日期或日期时间字段都以UTC/GMT(祖鲁时间)记录,以防止时区转换干扰我们的假设/计算(输入时需要将数据转换为UTC,提取时需要将数据转换为相关的当地时间)。我的建议(如下)中很可能存在错误(错误/遗漏);因为我没有测试此特定代码(尽管我编写了类似的代码)

    首先,让我们写一个查询,显示参加会议的总天数。我想我们不关心员工在某一天参加会议的时间(我们只关心他们当天是否参加会议)。为简单起见,我将忽略您的员工上白班/夜班的可能性(这样轮班/出勤可以从一天开始,一直持续到下一天),忽略紧急部署可能需要出勤超过24小时的可能性。我还假设紧急出勤从不发生在周六或其他被排除在外的日子。(否则,查询会有点复杂)。我建议:

    SELECT staff_id,COUNT(DATE(checked_in)) FROM tbl_attendance GROUP BY staff_id,DATE(checked_in) WHERE checked_in>:start_date AND checked_in<:end_date;
    
    -您可以在MySQL中执行此操作,但在其他一些玩具RDBMS系统(如MS Access)中则不行(其中必须包含一个伪“FROM”子句)

    接下来,我们将调整休假期间的查询,以排除假期(这需要子查询中的联接):

    选择员工id,SUM(DATEDIFF(有界结束日期,有界开始日期))+1-SUM(假期天数)作为休假天数,不包括假期
    从…起
    (选择
    职员身份证,
    如果(开始日期>:开始日期,开始日期,:开始日期)作为有界开始日期,
    
    如果(end_date=start_date AND holiday_date>=:start_date AND holiday_date事实上我对如何开始感到困惑OK,我会假设你对Laravel和Elountent有基本的了解,你的模型反映了这些关系。这里有一个基本的想法:获取所有员工和注意力,比如:
    $Staff=Staff::with('attendences')->get()
    。同时获取假期。现在迭代
    $staff
    $staff->attendences
    并检查
    $attendenc->checked_in
    是否不在假期,日期也不是周六。这只是一个,可能不是最好的解决方案,但在不知道您的应用程序的情况下,很难判断什么是最好的。实际上,这是付费的oll和考勤系统,员工工资通过其考勤生成。使用助手表作为日历存根,并计算其行(日期),这些行既不存在于
    考勤
    中,也不存在于
    假日
    ,也不存在于
    周六
    (可能是
    周日
    ?)这个问题应该是关于mysql的,而不是关于php或laravel的。请添加标记m
    $pdo=//You need to create a PDO object: see the manual for more information…
    $q=$pdo->prepare(SELECT staff_id,COUNT(DATE(checked_in)) AS attended_start_days FROM tbl_attendance GROUP BY staff_id,DATE(checked_in) WHERE checked_in>=:start_date AND checked_in<:end_date;);
    $q->bindValue(':start_date',$start_date,\PDO::PARAM_STR);
    $q->bindValue(':end_date',$start_date,\PDO::PARAM_STR);
    $q->execute();
    $staff_attended_start_days=$q->fetchAll(\PDO::FETCH_OBJ);
    //etc.
    
    SELECT COUNT(holiday_date) FROM tbl_holiday WHERE holiday_date>=:start_date AND holiday_date<end_date;
    
    SELECT staff_id,SUM(no_of_days) FROM tbl_leave GROUP BY staff_id WHERE start_date>=:start_date AND end_date<:end_date;
    
    SELECT staff_id,SUM(DATEDIFF(bounded_end_date,bounded_start_date))+1 
    FROM (SELECT staff_id,IF(start_date>:start_date,start_date,:start_date) AS bounded_start_date,IF(end_date<:end_date,end_date,:end_date) AS bounded_end_date FROM tbl_leave WHERE end_date>:start_date AND start_date<:end_date) AS qry_bounded_leave 
    GROUP BY staff_id;
    
    SELECT DATEDIFF(:end_date,:start_date)+1 AS days_in_range;
    
    SELECT staff_id,SUM(DATEDIFF(bounded_end_date,bounded_start_date))+1-SUM(holiday_days) AS leave_days_excluding_holidays 
    FROM 
        (SELECT 
            staff_id,
            IF(start_date>:start_date,start_date,:start_date) AS bounded_start_date,
            IF(end_date<:end_date,end_date,:end_date) AS bounded_end_date,
            COUNT(holiday_date) AS holiday_days 
        FROM tbl_leave INNER JOIN tbl_holiday ON (holiday_date>=start_date AND holiday_date>=:start_date AND holiday_date<end_date AND holiday_date<=:end_date) 
        GROUP BY staff_id,start_date,end_date
        WHERE end_date>:start_date AND start_date<:end_date
    ) AS qry_bounded_leave 
    GROUP BY staff_id;
    
    DATEDIFF(end_date,start_date) DIV 7 + IF(WEEKDAY(end_date)<WEEKDAY(start_date),1,0)