mysql - 具有特定凭据的连续天数

标签 mysql

我正在我工作的地方编写一份报告,该报告将帮助我们的行政部门计算假期应计金额。

如果您连续工作 40 小时,在第 5 年开始时,您会累积 10 小时,在第 10 年开始时,您会累积 12 小时。如果您最后休息一下,或者您工作了 40 小时,那么下降到 20,然后你的时间重置,直到你再次达到 40。

在我的数据库中,我有一个“工作进展”字段,它给出了“员工 ID”、职位的开始日期和结束日期。如果他们当前受雇,则结束日期为 NULL

这些是我正在使用的数据库中的一些字段:

+-----+-------+------------+------------+-------+    
| ID  | EmpID | startdate  | enddate    | hours |    
+-----+-------+------------+------------+-------+    
|   1 |     1 | 2011-06-01 | NULL       |    40 |   
|   2 |     2 | 2011-10-10 | NULL       |    40 |    
|   3 |     3 | 2000-03-01 | NULL       |    40 |    
|   5 |     5 | 1999-06-07 | NULL       |    40 |    
|   6 |     6 | 2012-05-16 | NULL       |    40 |    
|   7 |     7 | 1996-09-25 | NULL       |    40 |    
|   8 |     8 | 2015-10-07 | NULL       |    40    
|   9 |     8 | 2012-10-17 | 2015-10-06 |    40 |    
|  12 |     9 | 2000-06-05 | NULL       |    40 |
|  16 |    12 | 2005-08-04 | NULL       |    40 |    
|  17 |    13 | 2008-01-20 | NULL       |    40 |    
|  19 |    14 | 1999-02-17 | 2001-05-31 |    40 |    
|  22 |    16 | 2016-04-01 | NULL       |    40 |    
|  23 |    16 | 1999-11-01 | 2016-03-31 |    40 |    
|  29 |    18 | 1997-08-01 | NULL       |    40 |    
|  31 |    19 | 2012-02-13 | NULL       |    40 |    
|  36 |    22 | 2006-04-05 | NULL       |    40 |   
|  38 |    23 | 2015-07-01 | 2016-03-12 |    40 |    
|  44 |    27 | 2016-03-07 | 2017-03-03 |    40 |    
|  46 |    28 | 2002-11-11 | NULL       |    40 |    
|  47 |    29 | 2016-04-11 | NULL       |    40 |

所以我需要一个查询来查看用户 (EmpID) 上一个连续的完整时间(40 小时),然后检查它已经多少年了。

这是否有意义或可能?我见过很多例子,他们用单个日期来做,但没有一个用日期范围。

在计算这个字段时,我必须确保只包括最近的连续时间 40 小时。考虑这个例子:

一名员工从 2016 年 1 月 1 日到 2016 年 10 月 1 日每周工作 40 小时,因此他们有 9 个月的全职时间。然后他们从 2016 年 10 月 2 日到 2017 年 1 月 1 日转为兼职。然后在这段时间之后,他们从 2017 年 1 月 2 日到 2017 年 2 月 1 日回到全职,然后被提升到另一个部门,从 2017 年 2 月 1 日到今天仍然是全职。

我们要做的是忽略他们从 2016 年 1 月 1 日到 2016 年 10 月 1 日的工作时间,因为当他们去兼职时,他们失去了应计收入。现在他们从 2017 年 1 月 2 日到现在又开始了,我们确实必须将这些包括在计算中。

所以表格看起来像这样:

+-----+-------+------------+------------+-------+--------+    
| ID  | EmpID | startdate  | enddate    | hours |  Title | 
+-----+-------+------------+------------+-------+--------+    
|   1 |     1 | 2016-01-01 | 2016-10-01 |    40 | Job A  |  
|   2 |     1 | 2016-10-02 | 2017-01-01 |    20 | Job B  |   
|   3 |     1 | 2017-01-01 | 2017-02-01 |    40 | Job C  |
|   4 |     1 | 2017-02-02 | NULL       |    40 | Job D  |
+-----+-------+------------+------------+-------+--------+ 

所以由于ID 1在ID 2处有断点,并不会计算在并发时间,所以MySQL只能考虑ID 3 & 4记录的时间。

那么输出可能就像“EmpID - Diff Years”一样简单。 - 所以上面的示例正确输出应该是 1 - 0.8082 年

最佳答案

Demo (可能需要单击运行 (F8) 才能看到更新。)

我仍然不知道您到底在追求什么……每个员工的应计率?连续 40 小时服务的年数取决于我们如何处理年份,以及日期差异的总和是否适用于闰年等等......

SELECT EMPID
     , case when sum(yearsDiff) >= 5 and sum(yearsDiff) < 10 then 10
            when sum(yearsDiff) >= 10 then 12 end as AccrualRate
     , sum(yearsDiff) as CurrentConsecutive40HrYears
FROM (SELECT A.*
           , datediff(coalesce(endDate,curDate()),StartDate)/365 as YearsDiff
      FROM so46896406 A
      LEFT JOIN (SELECT max(endDate) AccStart, EmpID 
                 FROM SO46896406 
                 WHERE Hours < 40 
                 GROUP BY EmpID) B
        on A.EmpID = B.EmpID
      WHERE A.StartDate>=coalesce(B.AccStart,A.StartDate)
     )SUB
GROUP BY EmpID;

我使用 suquery 查找员工的工作的最大日期 < 40 小时。然后我将其用作最早可能的连续 40 小时范围。然后,我们使用日期差异对员工的所有条目求和,以查看总范围是否 > 5 年且 < 10,并将 10 指定为比率。如果 > 10,则速率为 12。任何低于 5 的比率都是 NULL。

我使用您的新数据添加了 empID 30,因为我不想重复原始集中的 1。它像你一样以 .8082 的形式出现。这导致应计率为空,因为应计率为 10 需要 < 5 年。

coalesce(b.AccStart,A.StartDate) 只是说保留所有开始日期大于最大非 40 小时日期的记录;但如果员工从未有过 40 小时的约会;只需返回该员工的所有记录。

现在我们可以将 where 子句简化为: WHERE B.AccStart is null OR A.StartDate >=B.AccStart; 因为我们只需要工作时间从未少于 40 岁的员工的记录;或那些工作较少的人;但我们只想要他们在日期之后的记录少于 40。

这两个记录都获得相同的结果;但是 WHERE A.StartDate>=coalesce(B.AccStart,A.StartDate) 应该更有效,因为它避免了由于 or 而对 A.StartDate 进行双索引搜索。

关于mysql - 具有特定凭据的连续天数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46896406/

相关文章:

c# - Mysql插入查询错误计数列不匹配

PHP,mysql - 使用 json_encode 中的 for 循环获取数据库表中的数据

mysql - 如何使用 JSF 和 PrimeFaces 将上传的文件作为 Blob 存储在 mysql 数据库中

python - 删除 SQLAlchemy 生成的查询中的引号

python - 将 MySQL 查询转换为 Django 查询

javascript - 如果我可以将文件路径保存在数据库中并将实际文件保存在存储中,为什么还要使用 Blob?

mysql - Prestashop:如何使用 ObjectModel 定义多个主键

mySQL - 每个页面的新表?

mysql - 尽管在 MySQL 4.1.25 中有效,但 MySQL 5.5 中的混合连接查询存在问题

MySQL权限问题: User cannot see database despite permission being granted to role