我有以下表格:
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日之前。
谢谢,
答案 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)
我找到了处理跨越日期的查询的最简单方法,例如存储StartDate
和EndDate
,其中EndDate
为NULL
当前工资。我使用触发器来确保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)