工资单应用程序-复杂的SQL查询


Payroll application - Complex SQL query

SQL FIDDLE此处:http://sqlfiddle.com/#!2/6c7f7/5**

我正在建立一个工资数据库,直到现在一切都很完美。我从一开始就没有提到的一个重要概念是,当员工的工资等级发生变化时,这会从工资等级变化的那一天起反映出来吗?以前,查询只会按照员工名字旁边的工资等级进行,但如果他的工资(例如)一周中每天都在变化,这是不准确的吗?

在其他人的帮助下,我已经达到了上面的SQL Fiddle,但结果并不能反映正确的答案。目前,该法案中的"where"条款使用了historyemployeepay表中不正确的工资率。它应该选择"null"ToDate行,并将其用作基本利率??有人能告诉我出了什么问题吗?

由于Jacob提供了一个选项,我也会对规范化进行一些更改。

Table PayCodes
PayCodeID  PayCodeDescription     timesBase  timesOtherRate timesMealRate
1          01 Ordinary            1.0        0.0            0.0
2          02 Overtime            1.5        0.0            0.0
3          03 Overtime            2.0        0.0            0.0
4          78 Crib                .333       0.0            0.0
5          CZ Meal Allowance PS   0.0        0.0            1.0
6          86Y Sick with Cert     1.0        0.0            0.0 
etc...

然后,在每小时表中,哪个数据条目将由数据驱动以获得相应的付款代码,保存内部ID代码与硬代码字引用。如果你不想显示任何神秘的引用,你甚至可以为"PayStubCaption"构建另一个专栏。

对于您的员工薪酬历史记录,字段是否包括开始/结束日期,因为这是一种罕见的情况(一年一次??可能两次??)既有给定薪酬的开始和结束日期,也包括(在本例中,您跟踪的3个薪酬。

PayHistoryID  EmployeeID  FromDate    ToDate     BaseRate  OtherRate  MealRate
1             84238       2012-10-10  2013-9-30  10.0      15.0       3.5      
2             84238       2013-10-1   (current)  14.0      21.0       6      
... 

这些可以显著帮助简化下游查询。。。

至于添加到要应用的每个费率的查询中,如果不允许错误数据,例如一条记录的从/到范围与同一个人的另一条记录交叉,这将成为一个简单的联接。。。

select
     ...
     sum( case/when...  PRT.BaseRate ) as ...
   from
      other join tables...
         JOIN PayRatesTable PRT
            on employeehours_copy.EmployeeID PRT.EmployeeID
           AND PRT.FromDate <= employeehours_copy.Worked
           AND ( PRT.ToDate IS NULL OR employeehours_copy.Worked <= PRT.ToDate )

注意,为了简化阅读,我将示例"PayRateTable"别名为PRT。然后每次计算都使用"PRT.BaseRate"或其他费率、餐费,而不是员工表中可能的费率。您还应该养成对所有table.column(或alias.column)进行模糊性问题限定的习惯,尤其是在每个表中列名相同的联接中。

我的建议是模块化更多。如果这是我的项目,我会创建一个处理每个时间段的过程。

假设鲍勃从1月1日上午8点到下午5点上班,1月2日上午11点到下午6点上班。1月1日,鲍勃赚了10美元,2日他赚了20美元。

我们的数据可能看起来像

Payrange
--------
Dec 20 2012 - Jan 01 2013 | $10
Jac 02 2013 - Jan 30 2013 | $20
Clock
-----
Jan 01 2013 | 9 hours
Jan 02 2013 | 7 hours

有了这些信息,您可以在之后对时钟的每一行求和,并将其与相应的支付范围相乘。