我有以下表结构:
NAME DEPT IN_DEPT OUT_DEPT
J. Smith Fin/Team1 2014-05-10 NULL
J. Smith Fin/Team2 2012-07-08 2014-05-09
J. Smith Fin/Team4 2011-10-11 2012-07-07
I. Ivanov Acc/Team2 2015-03-05 NULL
I. Ivanov Fin/Team2 2011-02-08 2015-03-04
我打算做一个财务部流动的时间表(外部 - 不在团队内部)。所以,我已经做了一个SELECT MIN(IN_DEPT),这很简单,我现在需要找到UNION的MAX(OUT_DEPT)结果。
但在那种情况下,J。史密斯仍在财务部门,所以MAX日期并不好。
我无法进行此查询,如果OUT_DEPT中有NULL值且DEPT值以'Fin'开头,则会抛弃NAME的所有其他结果。
目标表结果可能是这样的:
NAME DATE ACTION
I. Ivanov 2015-03-04 OUT
J. Smith 2011-10-11 IN
I. Ivanov 2011-02-08 IN
任何帮助表示赞赏。感谢。
答案 0 :(得分:1)
您需要确定人们何时进入财务并离开。这很棘手。以下是使用lag()
和lead()
的一种方法:
with cte as (
select t.*
from (select t.*,
lag(out_dept) over (partition by name order by in_dept) as prev_out,
lead(in_dept) over (partition by name order by in_dept) as next_in
from t
where dept like 'Fin%'
)
select name, in_dept, 'IN'
from t
where prev_out is null or prev_out <> in_dept - 1 day
union all
select name, out_dept, 'OUT'
from t
where next_in is null or next_in <> out_dept + 1 day;
答案 1 :(得分:0)
这应该有效。首先选择日期的最小值。接下来,这些日期与最大的出日期相结合,只有人被认为是谁离开了部门。这意味着没有OUT_DEPT的部门中不得存在名称。
SELECT NAME, MIN(IN_DEPT) DATE, 'IN' ACTION
FROM DEPARTMENT
WHERE DEPT LIKE 'Fin/%'
GROUP BY NAME
UNION ALL
SELECT D0.NAME, MAX(D0.OUT_DEPT) DATE, 'OUT' ACTION
FROM DEPARTMENT D0
WHERE DEPT LIKE 'Fin/%'
AND NOT EXISTS (
SELECT 1
FROM DEPARTMENT D1
WHERE D1.NAME = D0.NAME
AND D1.DEPT LIKE 'Fin/%'
AND D1.OUT_DEPT IS NULL )
GROUP BY NAME
但是,如果您拆分部门和团队或仅选择CTE中财务部门的记录,则NOT EXISTS
的条件会更好。
WITH DEPARTMENT_FIN (NAME, IN_DEPT, OUT_DEPT) AS (
SELECT NAME
,IN_DEPT
,OUT_DEPT
FROM DEPARTMENT
WHERE DEPT LIKE 'Fin%'
)
SELECT NAME, MIN(IN_DEPT) DATE, 'IN' ACTION
FROM DEPARTMENT_FIN
GROUP BY NAME
UNION ALL
SELECT D0.NAME, MAX(D0.OUT_DEPT) DATE, 'OUT' ACTION
FROM DEPARTMENT_FIN D0
WHERE NOT EXISTS (
SELECT 1
FROM DEPARTMENT_FIN D1
WHERE D1.NAME = D0.NAME
AND D1.OUT_DEPT IS NULL )
GROUP BY NAME