2013-12-18 40 views
3

我想重寫這個子查詢到一個連接。我已經閱讀了關於SO的其他問題,但無法讓這個工作。如何將數據庫子查詢重寫爲連接?

create table job (
    emplid int, 
    effdt date, 
    title varchar(100), 
    primary key (emplid, effdt) 
); 

insert into job set emplid=1, effdt='2010-01-01', title='Programmer'; 
insert into job set emplid=1, effdt='2011-01-01', title='Programmer I'; 
insert into job set emplid=1, effdt='2012-01-01', title='Programmer II'; 

insert into job set emplid=2, effdt='2010-01-01', title='Analyst'; 
insert into job set emplid=2, effdt='2011-01-01', title='Analyst I'; 
insert into job set emplid=2, effdt='2012-01-01', title='Analyst II'; 

#Get each employees current job: 
select * 
from job a 
where a.effdt= 
    (select max(b.effdt) 
    from job b 
    where b.emplid=a.emplid); 

結果:

+--------+------------+---------------+ 
| emplid | effdt  | title   | 
+--------+------------+---------------+ 
|  1 | 2012-01-01 | Programmer II | 
|  2 | 2012-01-01 | Analyst II | 
+--------+------------+---------------+ 

我想查詢改寫成聯接,沒有一個子查詢。這可能嗎?

回答

4

將此寫爲join可能有點違反直覺。這個想法是使用left outer join並且包含在b.effdt > a.effdt的條件下。除a.effdt取最大值外,此條件與行匹配。查詢然後可以篩選這些使用where

select a.* 
from job a left outer join 
    job b 
    on b.emplid = a.emplid and 
     b.effdt > a.effdt 
where b.effdt is NULL; 
0

您是否考慮重寫您的模式? 如果您有能力,最好有一個歷史記錄或日誌表,其中包含生效日期更改時的條目,哪個員工ID和以前的職位是什麼。這樣你就可以查詢實際的表並獲得你想要的結果。 這可以通過在數據庫中的某一行發生更改時使用觸發器來實現,然後在數據庫級別處理所有內容。