【问题标题】:SQL, join workdate to pay rate by effective dateSQL,加入workdate按生效日期支付利率
【发布时间】:2018-07-08 12:05:31
【问题描述】:

我有两张表,一张是员工工作日期,一张是每位员工的工资率以及这些工资率的生效时间。

它们看起来像这样:

CREATE TABLE pay_rates 
(
    [EMP ID] [int] NOT NULL,
    [RATE] [decimal](11, 6) NOT NULL,
    [EFFECTIVE DATE] [datetime] NOT NULL
)

CREATE TABLE work_dates
(
    [EMP ID] [int] NOT NULL,
    [WORK DATE] [datetime] NOT NULL,
)

pay_rates 表将为每位员工提供许多条目,因为他们的工资多年来一直在调整。

work_dates 表包含每位员工的工作日期。

这两个表都包含其他信息,但我已简化为相关列。

我想加入两者,这样我就可以看到每个工作日期的工资率。从技术上讲,我想将work_dates 中的每条记录加入pay_rates 中的记录,其中最大的EFFECTIVE DATE 小于WORK DATE 并且EMP ID 匹配。

【问题讨论】:

  • 那是无效的标准 SQL。您使用的是哪个 DBMS 产品? “SQL”只是一种查询语言,而不是特定数据库产品的名称。

标签: sql join


【解决方案1】:

也许当您将pay_rates 加入work_dates 时,您可以使用not exists 来要求不存在生效日期在工作日期或之前并且严格在生效日期之后的费率您加入的费率的日期。像这样的:

declare @pay_rates table (
    [EMP ID] [int] NOT NULL,
    [RATE] [decimal](11, 6) NOT NULL,
    [EFFECTIVE DATE] [datetime] NOT NULL
);

declare @work_dates table (
    [EMP ID] [int] NOT NULL,
    [WORK DATE] [datetime] NOT NULL
);

insert @pay_rates values
    (1, 10.25, '20160615'), 
    (1, 10.65, '20170101'), 
    (1, 11.85, '20180101');
insert @work_dates values 
    (1, '20160701'), 
    (1, '20170101'), 
    (1, '20170701'), 
    (1, '20171231'), 
    (1, '20180102');

select
    WorkDate.[EMP ID],
    WorkDate.[WORK DATE],
    Rate.RATE,
    Rate.[EFFECTIVE DATE]
from
    @work_dates WorkDate
    inner join @pay_rates Rate on
        WorkDate.[EMP ID] = Rate.[EMP ID] and
        WorkDate.[WORK DATE] >= Rate.[EFFECTIVE DATE] and
        not exists
        (
            select 1 
            from @pay_rates LaterRate 
            where
                LaterRate.[EMP ID] = WorkDate.[EMP ID] and
                LaterRate.[EFFECTIVE DATE] <= WorkDate.[WORK DATE] and
                LaterRate.[EFFECTIVE DATE] > Rate.[EFFECTIVE DATE]
        );

我在这里假设您不允许同一员工的两个工资率在同一日期生效。在这种情况下,上述查询将为使用这些费率的每个工作日期提供两个结果,因为它无法将一个优先于另一个。

【讨论】:

  • 这似乎有效。还是需要亲手翻查几条记录。我总是忘记我可以存在和不存在。
【解决方案2】:

我认为你需要:

SELECT pr2.[emp id], pr2.rate
FROM pay_rates pr2
INNER JOIN
(SELECT wd.[emp id], MAX(pr.[effective date]) AS mx_date
 FROM work_dates wd
 LEFT JOIN pay_rates pr
 ON (wd.[emp id] = pr.[emp id] AND wd.[work date] > pr.[effective date])
 GROUP BY wd.[emp id]) sub
ON pr2.[emp id] = sub.[emp id] AND pr2.[effective date] = sub.mx_date

在子查询中,选择每个emp id 小于员工工作日期的最大有效天数。然后将结果连接回工资率表以提取费率。

【讨论】:

    猜你喜欢
    • 2017-03-22
    • 2017-03-23
    • 1970-01-01
    • 1970-01-01
    • 2015-02-06
    • 2022-11-26
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    相关资源
    最近更新 更多