SQL Server 2012-检索日期介于两个日期之间的值

时间:2018-08-14 16:25:08

标签: sql sql-server sql-server-2012

我有一个称为“费率”的表格:

Valid From     Employee      Rate
----------------------------------
01/03/2010     1M            50
01/03/2010     2M            75
01/10/2015     1M            55
01/10/2015     2M            80

我还有下表称为“工作”:

ID        Employee         OpenedDate     Rate
100000    1M               05/06/2012
100000    2M               08/09/2018

如何从“费率”表中将费率检索到“工作”表中,其中“ OpenedDate”大于或等于当前的“有效期”日期,并且小于或等于下一个“有效期”日期(雇员也与之匹配)?

所以我最终会得到:

ID        Employee         OpenedDate     Rate
100000    1M               05/06/2012     50
100000    2M               08/09/2018     80

希望我解释得很好 为任何帮助加油!

ps不确定如何在Stack中以表格布局形式显示上述数据,一直在浏览帮助中,但看不到如何?

2 个答案:

答案 0 :(得分:5)

如果您无法修改表以添加“ ValidTo”列,则必须使用LEAD窗口函数动态创建一个

CREATE TABLE Table1
    ([Valid From] DATETIME, Employee varchar(2), Rate int)
;

INSERT INTO Table1
    ([Valid From], Employee, Rate)
VALUES
    ('2010-01-03 00:00:00', '1M', 50),
    ('2010-01-03 00:00:00', '2M', 75),
    ('2015-01-10 00:00:00', '1M', 55),
    ('2015-01-10 00:00:00', '2M', 80)
;

CREATE TABLE Table2
    (ID int, Employee varchar(2), OpenedDate DATETIME, Rate int)
;

INSERT INTO Table2
    (ID, Employee, OpenedDate, Rate)
VALUES
    (100000, '1M', '2012-05-06 00:00:00', NULL),
    (100000, '2M', '2018-08-09 00:00:00', NULL)
;

;WITH cteValidToAdded
AS(
    SELECT
         T1.[Valid From]
        ,[ValidTo] = ISNULL(LEAD(T1.[Valid From])OVER(PARTITION BY T1.Employee ORDER BY T1.[Valid From], T1.Employee),'25001212') --Some date in distance future
        ,T1.Employee
        ,T1.Rate 
    FROM dbo.Table1 T1
)
SELECT 
     T2.ID
    ,T2.Employee
    ,OpenedDate = CONVERT(VARCHAR(12), T2.OpenedDate, 101)
    ,V.Rate
FROM dbo.Table2 T2
LEFT JOIN cteValidToAdded V ON V.Employee = T2.Employee 
                            AND T2.OpenedDate >= V.[Valid From] AND T2.OpenedDate < V.ValidTo

输出

ID      Employee    OpenedDate  Rate
100000  1M          05/06/2012  50
100000  2M          08/09/2018  80

答案 1 :(得分:0)

只需使用outer apply

select j.*, r.rate
from jobs j outer apply
     (select top (1) r.*
      from rates r
      where r.employee = j.employee and
            r.valid_from <= j.opened_date
      order by r.valid_from desc
     ) r;

rates(employee, valid_from)(可能包括rate)上有一个索引,这应该比使用窗口函数的版本要快。