SELECT 忽略所有 NULL 发现及其亲属

SELECT which ignores all NULL findings and their relatives

我有以下 table 结构:

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),这很容易,我现在需要找到 MAX(OUT_DEPT) 到 UNION 的结果。

但在那种情况下,J. Smith 仍在财务部,因此 MAX 日期不合适。

我无法进行此查询,如果 OUT_DEPT 中有 NULL 值并且 DEPT 值以 'Fin' 开头,它会抛出 NAME 的所有其他发现.

目标table结果可能是这样的:

NAME        DATE         ACTION
I. Ivanov   2015-03-04   OUT
J. Smith    2011-10-11   IN
I. Ivanov   2011-02-08   IN

感谢任何帮助。谢谢

您需要确定人们何时进入金融领域和何时离开。这很棘手。这是使用 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;

这应该有效。首先 select 日期中的最小值。接下来,将这些日期与离职日期的最大值结合起来,其中只考虑离开部门的人。这意味着部门中不能存在没有 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

但是,如果您拆分部门和团队,或者 select 仅在 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