aphrek
aphrek

Reputation: 59

Selecting most recent child record from master table based on date

I'm trying to combine the data in two tables. The first (child) table contains some payment information with an effective date, employee number & payment value.

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

The other (master) table contains employee number, effective date & job title.

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

I need to report on the pay information table & display which job title was in place at the time of the pay informations effective date:

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

I've tried using a correlated query such as:

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

but based on the example above would give me the job Tester for all rows. I'd really appreciate it if someone can help on this. Many thanks.

Upvotes: 0

Views: 722

Answers (1)

BradBrening
BradBrening

Reputation: 5518

You need an ORDER BY in your SELECT from emp_hist - otherwise the first record "Tester" always satisfies your condition and is returned first.

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

However, in this instance I believe a CROSS APPLY query can be your friend. Once you've mastered its usage, you'll find yourself using it time and time again. A good rule of thumb is that if you're considering using a SELECT TOP * in an inline view - stop and use an APPLY query instead. IMHO it makes your SQL much easier to read and understand and I'd venture that it makes your query more efficient.

You could re-write your query using a CROSS APPLY like so:

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

I haven't run this, but I believe it should work.

Upvotes: 1

Related Questions