2012-02-07 58 views
2

您好我有一個表如下如何從列表中選擇上次薪資更改日期?

EmplID  Name  Effdt   Salary Action 

1000  XXXX  01-01-2010  5000  HIR  ----hire 
1000  XXXX  01-05-2011  6000  PRO  ----promotion 
1000  XXXX  01-03-2012  6000  TER  -----TErminate 
1001  YYYY  01-01-2010  8000  HIR  ----hire 
1001  YYYY  01-05-2011  6000  PRO  ----promotion 
1001  YYYY  01-03-2012  4000  Trn  -----TRANSFER 
1001  yyyy  01-04-2012  4000  TER  -----TERMINATE 

從上面的表格我想選擇薪水更改日期爲:

EMPLID EFFDT 
1000 01-05-2011 
1001 01-03-2012 

能否請你幫忙嗎?

+0

等待,在您的示例輸出數據中,empl 1001的日期是* not *最近的更改。這是一個錯誤嗎? – 2012-02-07 15:15:31

+0

最近的1001將是2011年1月5日,不01-03-2011。 – 2012-02-07 15:16:11

+0

他想要我想到的更改日期,而不是最近的日期,即01-05-2011作爲工資變化5000-> 6000和01-03-2012,因爲它從6000-> 4000這引發了問題什麼是多個變化的輸出?最近的?是否有具體的行動產生變化? – 2012-02-07 15:20:33

回答

3

你可以試試這個查詢(假設終止日期不會改變工資和所有其他的事情,包括出租):

SELECT EMPLID, MAX(Effdt) 
FROM Tble 
WHERE Action != 'TER' 
GROUP BY EMPLID 

這組由僱主ID和組內選擇的最後日期。

+0

看一看,OP搜索第二個最大日期。請參閱@AlexK評論。 – danihp 2012-02-07 15:19:33

+0

用戶1000的最後日期爲01-03-2012。我認爲這不是一個錯誤。 – danihp 2012-02-07 15:21:24

2

這是一個非常簡單的MAX()聚集在Effdt。我會建議在SQL聚合函數和GROUP BY條款讀了起來,因爲這是一個基本的任務。

SELECT 
    EmplID, 
    MAX(Effdt) AS LastChange 
FROM employees 
GROUP BY EmplID 
+0

看看,OP搜索第二個最大日期。請參閱@AlexK評論。 – danihp 2012-02-07 15:19:45

+1

這樣的錯誤(回答一個問題與OP的意圖不同)是爲了避免潛在的讚美言論的原因;)* [不是我曾經學過這門課,但是] * – MatBailie 2012-02-07 15:33:31

0

你應該獲得最大的第二次約會:最大日期不包括真正的最大日期:

Select taf.emplid, max(taf.Effdt) 
from 
    tableAsFollows taf 
inner join 
    (Select emplid, max(Effdt) 
    from 
    tableAsFollows taf2 
    group by emplid) t_max 
on taf.emlpid = t_max.emplid 
where taf.Effdt < t_max.Effdt 
group by taf.emplid 

如果你的DBMS支持CTE然後用它insteat這種方法。

+0

它看起來像問題的某個地方有一個錯誤,因爲對於用戶1000,他輸出最後的日期 – Tim 2012-02-07 15:19:20

+0

它不是。重新讀取樣本數據。 – danihp 2012-02-07 15:24:36

+0

我不會假設最後一次*更改始終是最後一條記錄的第二條記錄,那麼還沒有終止的員工呢?有可能假定你應該忽略TER行動記錄,如果它們存在... – MatBailie 2012-02-07 15:30:42

0

假設錄用和終止不計入工資的變化,你需要添和邁克爾的答案稍有不同。

SELECT 
    EmplID, 
    MAX(Effdt) AS LastChange 
FROM employees 
WHERE Action NOT IN ('HIR','TER') 
GROUP BY EmplID 

可能有其他行爲不符合「薪水變動」的條件。如果是這樣,請將它們添加到WHERE子句中。或者,您可以在WHERE條款中使用包含列表。

0

假設最後一次更改並不總是最後一條記錄的第二次更改,並且它可能位於鏈中的任何位置。

SELECT 
    current.EmplID, 
    COALESCE(MAX(next.Effdt), current.Effdt) 
FROM 
    yourTable AS current 
LEFT JOIN 
    yourTable AS next 
    ON next.EmplID = current.EmplID 
    AND next.Effdt = (SELECT MIN(Effdt) 
         FROM yourTable AS lookup 
         WHERE EmplID = current.EmplID 
         AND Effdt > current.Effdt) 
    AND current.Salary <> next.Salary 
GROUP BY 
    current.EmplID 

(左JOIN和COALESCE()只有一個項目的連鎖應付)


如果只有時間可以有一個新的紀錄,同樣的薪水是在終端,你可以不理會終止記錄...

SELECT EMPLID, MAX(Effdt) 
FROM  yourTable 
WHERE Action != 'TER' 
GROUP BY EMPLID 


要獲得最好的解決方案,我們需要知道更多。您需要準確描述數據如何表現:)

0

如果您的dbms支持CTE,並且可以排除終止的薪水。然後像這樣的東西可能會訣竅:

;WITH CTE 
AS 
(
SELECT 
    RANK() OVER(PARTITION BY EmplID ORDER BY Effdt DESC) AS iRank, 
    tbl.EmplID, 
    tbl.Effdt 
FROM 
    yourTable AS tbl 
WHERE 
    tbl.[Action]!='TER' 
) 
SELECT 
    * 
FROM 
    CTE 
WHERE 
    CTE.iRank=1 
相關問題