在SQL中选择最长的工作员工

时间:2016-02-28 18:40:35

标签: mysql sql

我的数据库看起来像:

表:dept_emp

+--------------------------+-----------------------+------------------------+
| emp_no (Employee Number) | from_date (Hire date) | to_date (Worked up to) |
+--------------------------+-----------------------+------------------------+
|                        5 | 1995-02-27            | 2001-01-19             |
|                      500 | 1968-01-01            | 9999-01-01             |
+--------------------------+-----------------------+------------------------+

注意:如果员工目前仍在为公司工作,他们的to_date将显示9999-01-01

我想要做的是显示最长工作员工的emp_no。我不确定如何使用数据库中的随机9999-01-01来做到这一点。

这是我到目前为止所提出的:

SELECT emp_no 
  FROM (SELECT max(datediff( (SELECT to_date 
                                FROM dept_emp), 
                             (SELECT from_date 
                                FROM dept_emp)
                           )
                  )
       );

这不起作用,也不考虑9999-01-01

我想我应该在他们的某些地方使用CURDATE()

5 个答案:

答案 0 :(得分:1)

首先我建议将to_date设为DEFAULT NULL。 你想在那里有NULL,如果员工仍在工作,不需要9999件。

现在,关于工作时间最长的员工的问题。您可以像这样计算日期差异,将NULL视为今天的日期:

SELECT emp_no, MAX(DATEDIFF( IFNULL(to_date,CURDATE()) ,from_date)) FROM dept_emp;

我们所做的是,如果to_date为NULL,意味着人仍然受雇,我们假设他的to_date是今天的日期,这是真的。

编辑:很抱歉,忘记返回员工编号,只需将emp_no添加到查询中即可。

编辑2:由于您不允许使用NULL,因此您应该这样做:

  SELECT emp_no, MAX(DATEDIFF( IF(to_date='9999-01-01',CURDATE(), to_date) ,from_date)) FROM dept_emp;

基本上,我们说如果设置了9999-,则将其用作今天的日期。希望这可以帮助。我认为除了9999之外,没有人会比今天的日期更大。

编辑3:你对emp_no是对的,所以在这里:

SELECT emp_no, DATEDIFF( IF(to_date='9999-01-01',CURDATE(), to_date) 
,from_date) as longest_date FROM dept_emp ORDER BY longest_date DESC LIMIT 0,1;

答案 1 :(得分:1)

您可以尝试这样的事情:

select 
  d.*,
  datediff(
    case when to_date = '9999-01-01' then current_date else to_date end,
    from_date) as how_long
from dept_emp d
where 
datediff(
    case when to_date = '9999-01-01' then current_date else to_date end,
    from_date) = (

  -- find the longest tenure
  select max(datediff(
    case when to_date = '9999-01-01' then current_date else to_date end,
    from_date))
  from dept_emp

)

如果这是您表中的信息类型:

create table dept_emp (
  emp_no int,
  from_date date,
  to_date date
);
insert into dept_emp values 
(1, '2000-01-01', '2000-01-02'),
(2, '2000-01-01', '2005-02-01'),
(3, '2000-01-01', '9999-01-01');

您的结果将是:

| emp_no |                 from_date |                   to_date | how_long |
|--------|---------------------------|---------------------------|----------|
|      3 | January, 01 2000 00:00:00 | January, 01 9999 00:00:00 |     5902 |

示例SQLFiddle:http://sqlfiddle.com/#!9/55886/11

答案 2 :(得分:0)

假设你想要仍然受雇的最长终身工(即他们的to_date = '9999-01-01'),那么这应该有效:

select emp_no 
from dept_emp 
where to_date = '9999-01-01' and 
datediff(to_date, from_date) = 
( 
   select max(datediff(to_date, from_date)) 
   from dept_emp where to_date = '9999-01-01'
);

答案 3 :(得分:0)

这将返回工作时间最长的员工ID。请注意,CTE不一定纯粹是为了便于阅读。如果您要获得性能,请参阅第二个查询。你可以解决'9999-01-01'使用像这样的Case语句的最大日期问题。

使用CTE:

;with cte_stage as (
    select emp_no
    ,case when to_date = '9999-01-01' 
         then DateDiff(DAY,from_date,GETDATE()) 
         else DATEDIFF(DAY,from_date,to_date) END as 'age'
     from dept_emp
)
select emp_no
from cte_stage
where age = ( select max(age) from cte_stage)

没有CTE:

select emp_no
from dept_emp
where case 
    when to_date = '9999-01-01' 
    then DateDiff(DAY,from_date,GETDATE()) 
    else DATEDIFF(DAY,from_date,to_date) END  = 
    ( 
         select max( 
              case 
                   when to_date = '9999-01-01' 
                   then DateDiff(DAY,from_date,GETDATE()) 
                   else DATEDIFF(DAY,from_date,to_date) 
               END 
          ) 
    from dept_emp)

答案 4 :(得分:0)

如果员工人数不多,有一个简单的解决方案:

SELECT
  *, datediff(to_date, from_date) AS duration
FROM (
  SELECT
    emp_no, from_date, IF(to_date <> '9999-01-01', to_date, CURRENT_DATE) AS to_date
  FROM
    dept_emp
) AS tmp
ORDER BY duration DESC
LIMIT 1

这使用子选择将'9999-01-01'值替换为CURRENT_DATE,然后按持续时间排序结果,并获得第一个员工。 同样,如果表中的行数不是太大,这就足够了。

  

这是SQL Fiddle

     

示例数据:

INSERT INTO dept_emp VALUES
(500, '1968-01-01', '2016-01-05'),
(650, '1970-01-01', '9999-01-01'),
(700, '2006-01-01', '2016-01-01');
     

结果:

| emp_no |                 from_date |                   to_date | duration |
|--------|---------------------------|---------------------------|----------|
|    500 | January, 01 1968 00:00:00 | January, 05 2016 00:00:00 |    17536 |

以下是有关控制流功能的官方MySQL文档: