员工数据库随着时间的推移而变化

时间:2010-02-15 03:48:41

标签: sql join schema

我有以下表格:

PROJECTS - project_id, name
EMPLOYEES - employee_id, name
SALARY - employee_id, date, per_hour
HOURS - log_id, project_id, employee_id, date, num_hours

我需要查询项目的成本。问题是薪水可能会有所不同。例如,一个人可以加薪。

SALARY表记录员工的per_hour费用。每次成本变化都记录在日期中。

如何查询此信息以确保HOURS表中的日志始终与SALARY表中的右侧条目匹配。正确匹配...取决于小时日志的日期,从工资表中获取具有日志日期之前的最高日期的行。

即..如果工作是在2月14日进行的。从具有最高日期的Salary表中获取该员工的行..但仍然在14日之前。

谢谢,

3 个答案:

答案 0 :(得分:2)

您需要的是SALARY的结束日期。将新记录插入到员工的SALARY中时,具有最高日期的先前记录(或者更好的是,当前标记设置为由cletus建议的'Y')应将其结束日期列设置为与该日期相同的日期。新记录的开始日期。

这应该适用于您当前的架构,但要注意它可能很慢。

SELECT
  SUM(h.num_hours * s.per_hour) AS cost
FROM PROJECTS p
INNER JOIN HOURS h
  ON p.project_id = h.project_id
INNER JOIN (
    SELECT
      s1.employee_id,
      s1.date AS start_date,
      MIN(s2.date) AS end_date
    FROM SALARY s1
    INNER JOIN SALARY s2
      ON s1.employee_id = s2.employee_id
      AND s1.date < s2.date
    GROUP BY
      s1.employee_id,
      s1.date) s
  ON h.employee_id = s.employee_id
  AND h.date >= s.start_date
  AND h.date < s.end_date

答案 1 :(得分:0)

在“小时”表中,实际记录您使用的工资的值(不要根据ID链接它)。这将为您提供更大的灵活性。

答案 2 :(得分:0)

我找到了处理跨越日期的查询的最简单方法,例如存储StartDateEndDate,其中EndDateNULL当前工资。我使用触发器来确保NULL只有一个EndDate值,并且没有重叠的日期范围或范围之间的间隙。 StartDate不可为空,因为它永远不是有效值。

然后您的加入非常简单:

select h.num_hours, s.per_hour
from hours h
inner join salary s on h.employee_id = s.employee_id 
    and h.date >= s.StartDate and (h.date <= s.EndDate or s.EndDate is null)