如何从员工历史记录表中获取第一个和最后一个日期/记录

时间:2015-06-15 10:18:33

标签: sql oracle

让我们说emp是在4月10日雇用并于4月30日转移并在6月15日再次升级。所以从这段历史我需要emp_data的第一个和最后一个(最近的记录)。 action_date是上面提到的日期。所以我需要10月10日和10月6日作为我的查询的输出。行动被称为雇用,转移等。

这就是我正在尝试的 -

select empid, action, action_dt from ps_job where
action_dt in (select min(action_dt), max(action_dt) from ps_job where empid='88888'); 

但它却向我展示了记录中的所有3个日期。

4 个答案:

答案 0 :(得分:1)

我认为您必须将查询修改为以下内容:

select empid, action, action_dt 
from ps_job 
where action_dt in (select min(action_dt) 
                    from ps_job 
                    where empid='88888'

                    UNION ALL

                    select max(action_dt)
                    from ps_job 
                    where empid='88888')

MINMAX应选择为两个单独的行,以便IN子句有效。一种方法是使用UNION,如上面的查询。

Demo here

或者,您可以使用ROW_NUMBER

SELECT empid, action, action_dt
FROM (
select empid, action, action_dt,
       ROW_NUMBER() OVER (PARTITION BY empid ORDER BY action_dt) AS frn,
       ROW_NUMBER() OVER (PARTITION BY empid ORDER BY action_dt DESC) AS lrn
from ps_job ) t
WHERE frn = 1 OR lrn = 1

请注意,此版本不等同于第一个查询,因为可能有多个记录具有相同的最大或最小日期。如果您希望选择所有最多,最小记录,则必须将ROW_NUMBER替换为RANK

Demo here

答案 1 :(得分:0)

首次选择后,您需要执行MIN和MAX功能。

如果你使用两个不同的查询尝试类似(未测试):

select empid, action, MIN(action_dt) from ps_job where empid='88888')
UNION
select empid, action, MAX(action_dt) from ps_job where empid='88888'); 

答案 2 :(得分:0)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE ps_job ( empid, action, action_dt ) AS
          SELECT 88888, 'Join',     DATE '2015-04-10' FROM DUAL
UNION ALL SELECT 88888, 'Transfer', DATE '2015-04-30' FROM DUAL
UNION ALL SELECT 88888, 'Promote',  DATE '2015-06-10' FROM DUAL; 

查询1

SELECT empid,
       MIN( action ) KEEP ( DENSE_RANK FIRST ORDER BY action_dt ) AS action,
       MIN( action_dt ) AS action_dt
FROM   ps_job
WHERE  empid = 88888
GROUP BY
       empid
UNION ALL
SELECT empid,
       MAX( action ) KEEP ( DENSE_RANK LAST ORDER BY action_dt ) AS action,
       MAX( action_dt ) AS action_dt
FROM   ps_job
WHERE  empid = 88888
GROUP BY
       empid

<强> Results

| EMPID |  ACTION |               ACTION_DT |
|-------|---------|-------------------------|
| 88888 |    Join | April, 10 2015 00:00:00 |
| 88888 | Promote |  June, 10 2015 00:00:00 |

查询2

SELECT empid,
       MIN( action ) KEEP ( DENSE_RANK FIRST ORDER BY action_dt ) AS first_action,
       MIN( action_dt ) AS first_action_dt,
       MAX( action ) KEEP ( DENSE_RANK LAST ORDER BY action_dt ) AS last_action,
       MAX( action_dt ) AS last_action_dt
FROM   ps_job
WHERE  empid = 88888
GROUP BY
       empid

<强> Results

| EMPID | FIRST_ACTION |         FIRST_ACTION_DT | LAST_ACTION |         LAST_ACTION_DT |
|-------|--------------|-------------------------|-------------|------------------------|
| 88888 |         Join | April, 10 2015 00:00:00 |     Promote | June, 10 2015 00:00:00 |

答案 3 :(得分:0)

另一种解决方案,与@GiorgosBetsos非常相似。但这避免了ORDER BY内的两个ROW_NUMBER,现在两个窗口聚合都可以在同一步骤中计算:

SELECT empid, action, action_dt
FROM
 (
   select empid, action, action_dt,
       ROW_NUMBER() OVER (PARTITION BY empid ORDER BY action_dt) AS rn,
       COUNT(*) OVER (PARTITION BY empid) AS cnt
   from ps_job
 ) t
WHERE rn in (1, cnt)

Fiddle