我正在尝试撰写一份报告,该报告将在工作时加入一个人,他们的工作和他们的小时工资。当日期小于工作日期时,我似乎无法找出加入此人费用的最佳方式。
假设一个人在年初每小时花费30美元,然后在2月5日获得10美元的加薪,在3月1日获得另一个加注。
这个人花了几个小时的时间来跨越rasies。
我正在尝试编写一个SQL语句,它将提取小时数,每小时费用和小时费用。成本是最后输入系统的小时费率,因此成本日期小于工作日期,按成本日期限制1排序。
SELECT person.id, person.name, work.hours, person_costs.value,
work.hours * person_costs.value AS value
FROM person
JOIN work ON person.id = work.person_id
JOIN person_costs ON person.id = person_costs.person_id
AND person_costs.date < work.date
WHERE person.id = 1234
ORDER BY work.date ASC
我遇到的问题是,person_costs没有按日期降序排序。它正在拉出符合条件的“任何”值(自然按记录位置排序)。如何选择早于工作日期的第一个person_cost值?
谢谢!
答案 0 :(得分:0)
最佳解决方案是更改person_costs表,以便记录日期间隔(开始和结束)的价格,而不是更改后的价格。只要您不创建任何重叠间隔,连接将始终每人/日期只获取一行。
如果无法更改表结构,则可以创建一个实现相同效果的视图。
答案 1 :(得分:0)
这是我的测试架构:
Create Table person_cost
(
PersonId int not null
, Rate decimal(15,4) not null
, [date] datetime not null
, Constraint PK_person_cost Primary Key Clustered ( PersonId, [date] )
)
Insert person_cost(PersonId, Rate, [date]) Values(1,30,'2010-01-01')
Insert person_cost(PersonId, Rate, [date]) Values(1,40,'2010-02-05')
Insert person_cost(PersonId, Rate, [date]) Values(1,50,'2010-03-01')
Create Table Work
(
PersonId int not null
, [Date] datetime not null
, Hours int not null
)
Insert Work(PersonId, [Date], Hours) Values(1, '2010-01-05', 10)
Insert Work(PersonId, [Date], Hours) Values(1, '2010-01-27', 5)
Insert Work(PersonId, [Date], Hours) Values(1, '2010-02-10', 10)
Insert Work(PersonId, [Date], Hours) Values(1, '2010-03-03', 5)
我的疑问:
Select Work.PersonId, Work.Hours, PayRanges.Rate
, Work.Hours * PayRanges.Rate As Value
From Work
Join (
Select pc1.PersonId, pc1.[date] As StartDate, Rate
, Coalesce((Select Min(pc2.[date])
From person_cost As pc2
Where pc2.personId = pc1.personId
And pc2.[date] > pc1.[date])
, '9999-12-31') As NextEffectiveDate
From person_cost As pc1
) As PayRanges
On Work.PersonId = PayRanges.PersonId
And Work.[Date] >= PayRanges.StartDate
And Work.[Date] < PayRanges.NextEffectiveDate
实质上,我计算了有效工资率的结束日期。在我的示例中,我将连接排除在Person表之外,但是可以很容易地将其包括在内以获取Person数据。请注意,我计算工资率的到期日期将是下一个工资率生效的日期,因此我查询的价值严格低于到期日。