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

时间:2013-12-16 06:45:49

标签: php mysql sql

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

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

在其他人的帮助下,我已经达到了上面的SQL小提琴,但结果并没有反映出正确的答案。目前,该小提琴中的“where”子句使用了historyemployeepay表中不正确的工资率。它应该选择'null'ToDate行并使用它作为基本速率?有人能告诉我出了什么问题吗?

2 个答案:

答案 0 :(得分:1)

正如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      
... 

这些可以极大地帮助简化查询下游......

至于添加到要应用的每个速率的查询,如果你不允许坏数据,这将成为一个简单的连接,例如一个记录上的from / to范围与同一个人的另一个记录的另一个。

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)限定歧义问题的习惯,特别是在每个表中列名相同的连接时。(/ p>

答案 1 :(得分:0)

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

让我们说鲍勃在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

使用此信息,您可以将之后的每一行时间加总将其与相应的支付范围相乘。