2012-02-07 56 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 
相关问题