SELECT忽略所有NULL结果及其亲属

时间:2015-11-06 14:08:07

标签: sql db2

我有以下表结构:

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

任何帮助表示赞赏。感谢。

2 个答案:

答案 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