MySQL - 如何内部连接对连接数据进行排序

时间:2010-04-05 04:27:53

标签: sql mysql join

我正在尝试撰写一份报告,该报告将在工作时加入一个人,他们的工作和他们的小时工资。当日期小于工作日期时,我似乎无法找出加入此人费用的最佳方式。

假设一个人在年初每小时花费30美元,然后在2月5日获得10美元的加薪,在3月1日获得另一个加注。

  • 01/01/2010 $ 30.00(每小时)
  • 02/05/2010 $ 40.00
  • 03/01/2010 $ 45.00

这个人花了几个小时的时间来跨越rasies。

  • 01/05/2010 10小时(应该是30美元/小时)
  • 01/27/2010 5小时(再次30美元)
  • 02/10/2010 10小时(每小时40美元)
  • 03/03/2010 5小时(每小时45美元)

我正在尝试编写一个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值?

谢谢!

2 个答案:

答案 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数据。请注意,我计算工资率的到期日期将是下一个工资率生效的日期,因此我查询的价值严格低于到期日。