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
我有以下 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