根据日期从主表中选择最近的子记录

时间:2012-08-21 13:37:02

标签: sql-server tsql

我正在尝试将数据合并到两个表中。第一个(子)表包含一些付款信息,其中包含生效日期,员工编号和安排。付款价值。

emp_no  date_earn   Amount
456789  03/10/2009  20
456789  18/03/2010  30
456789  17/03/2011  12
456789  16/03/2012  34

另一个(主)表包含员工编号,生效日期和时间。职称。

emp_no  effective_date  job_title 
456789  01/01/2009      Tester
456789  20/05/2010      Manager
456789  01/04/2011      Snr Manager

我需要报告薪资信息表&在薪酬信息生效日期显示哪个职称已到位:

emp_no  date_earn   Amount  job_title 
456789  03/10/2009  20      Tester
456789  18/03/2010  30      Manager
456789  17/03/2011  12      Manager
456789  16/03/2012  34      Snr Manager

我尝试过使用相关查询,例如:

select p.emp_no, p.date_earn, p.amount,
(select top 1 e.job_title from emp_hist e
where e.emp_no = p.emp_no
and e.effective_date <= p.date_earn ) as JOB_TITLE
from 
pay p where p.emp_no = 456789

但基于上面的例子会给我所有行的作业测试器。如果有人可以提供帮助,我真的很感激。非常感谢。

1 个答案:

答案 0 :(得分:1)

你需要从emp_hist中选择一个ORDER BY - 否则第一个记录“Tester”总是满足你的条件并首先返回。

where e.emp_no = p.emp_no and e.effective_date <= p.date_earn order by e.effective_date desc

但是,在这种情况下,我相信CROSS APPLY查询可以是您的朋友。一旦你掌握了它的用法,你就会发现自己一次又一次地使用它。一个好的经验法则是,如果您正在考虑在内联视图中使用SELECT TOP * - 请停止并使用APPLY查询。恕我直言,它使您的SQL更容易阅读和理解,我敢冒险,它使您的查询更有效。

您可以使用CROSS APPLY重写您的查询,如下所示:

SELECT
   P.emp_no
  ,P.date_earn
  ,P.amount
  ,T.job_title
FROM
  pay P
  CROSS APPLY (
    SELECT TOP 1
      E.job_title
    FROM
      emp_hist E
    WHERE
      E.emp_no = P.emp_no
      AND E.effective_date <= P.date_earn
    ORDER BY
      E.effective_date DESC
  ) T
WHERE
  P.emp_no = 456789

我没有这样做,但我相信它应该有用。