我的数据如下表所示:
EMPLOYEE_NUM START_DTM END_DTM
47567567446 5/9/2019 12:00:00 PM
76475676575675756 5/10/2019 12:00:00 PM 5/10/2019 11:59:59 PM
456756765767 5/3/2019 12:00:00 PM 5/8/2019 11:59:59 PM
74676576764565 5/2/2019 12:00:00 PM 5/8/2019 11:59:59 PM
98695689576 5/1/2019 12:00:00 PM
我要检索符合以下条件的employee_num:
如果有任何条目的NULL作为end_dtm, 然后使用max(start_dtm)和end_dtm为null的employee_num打印
如果没有条目以NULL作为end_dtm, 然后使用end_dtm = max(end_dtm)打印employee_num
我尝试过
select
decode(select count(1) from employee where end_dtm is null,
0,
select employee_num where end_dtm=(select max(end_dtm) from employee),
select employee_num where start_dtm=(select max(start_dtm) from employee where end_dtm is null),
) from dual
看起来这不是有效的查询。 有人可以帮忙吗?
答案 0 :(得分:1)
因此,您必须先区分END_DTM为空还是非空,然后才考虑使用END_DTM或START_DTM进行进一步排序。
对于第一部分,功能NVL2正是您所需要的。它需要三个参数。当第一个参数为非null时,它将返回第二个参数,而当第三个参数为null时,它将返回第三个参数。因此:如果日期不为null,则NVL2(END_DTM,1,0)将返回1,如果日期为null,则返回0。然后,您可以再次使用NVL2,当它不为空时选择END_DTM,但当它不为空时选择START_DTM。
然后可以在ORDER BY子句中使用它来定义ROW_NUMBER(),如下所示:
select [whatever]
from
( select t.*,
row_number() over (order by nvl2(END_DTM, 1, 0),
nvl2(END_DTM, END_DTM, START_DTM) desc) rn
from your_table t
)
where rn = 1
;
如果END_DTM总是非空(或者如果总是空),则第一个NVL2值是恒定的,因此仅按END_DTM排序(如果END_DTM总是非空),则分别为。按START_DTM(如果END_DTM始终为空)。但是,如果混合使用空和非空END_DTM,则只有具有空END_DTM的那些才被第一个排序标准约束,然后仅考虑那些行来选择最大START_DTM。
答案 1 :(得分:0)
我本可以使用analytical
函数,如下所示:
Select employee_num from
(Select t.employee_num
Sum(case when end_dtm is null then 1 end) as cnt,
Row_number()
over (order by end_dtm desc nulls last) as end_dtm_rn,
Row_number()
over (order by case when end_dtm is null then start_dtm end desc nulls last) as start_dtm_rn
From employee t)
Where case when cnt = 0
then end_dtm_rn
Else start_dtm_rn end = 1;
干杯!
答案 2 :(得分:-1)
只需使用聚合和case
:
select employee_num,
(case when count(*) = count(end_dtm) -- no nulls
then max(end_dtm)
else max(start_dtm)
end)
from t
group by employee_num;
如果要在原始数据中每行 ,请使用解析函数:
select t.*,
(case when count(*) over (partition by employee_num) = count(end_dtm) over (partition by employee_num) -- no nulls
then max(end_dtm) over (partition by employee_num)
else max(start_dtm) over (partition by employee_num)
end)
from t;
编辑:
关于您想要的内容的另一种解读表明,您需要一个employee_num
子查询来满足您的条件。如果是这样,那就更简单了:
select t.*
from (select t.*
from t
order by (case when end_dtm is null then 1 else 2 end), -- nulls first
start_dtm desc
) t
where rownum = 1;