Reputation: 59
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
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