我的数据库看起来像:
表: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()
?
答案 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文档: