如何在Oracle表中找到月份差距?

时间:2017-11-07 14:10:07

标签: sql oracle gaps-and-islands

我有一个Oracle表,其中包含EmpName(Char),Month_from和Month_to列(Numeric)。在这里,我需要找到缺失的月份(月份差距)。在下面的示例数据中,我必须找到丢失的第6个月(6月)。

提前致谢。

Sample Data:

|-------|-----------|--------|
|eName  |Month_From |Month_To|
|(Char) | ( Int)    | ( Int) |
|-------|------------|-------|
|John   |1          |2       | ( Jan to Feb)
|John   |3          |5       | ( Mar to May)
|John   |7          |8       | ( Jul to Aug)    
|-------|------------|-------|

需要查找(Jun到Jun)。

2 个答案:

答案 0 :(得分:3)

假设没有重叠,您可以使用lag()找到丢失的月份:

select (prev_month_to + 1) as start_missing,
       (month_from - 1) as end_missing
from (select t.*, lag(month_to) over (partition by name order by month_from) as prev_month_to
      from t
     ) t
where prev_month_to <> month_from - 1;

这为每个差距提供了一个范围,因为差距可能超过一个月。

答案 1 :(得分:1)

只需转换示例数据,您可以考虑:

select to_char(to_date(lpad(t.month_from,2,'0'),'mm'),'Mon')||' to '||
       to_char(to_date(lpad(t.month_to,2,'0'),'mm'),'Mon')
  from my_table t
 where upper(t.eName) = upper('&i_eName');

对于问题( Jun to Jun ):

select to_char(to_date(lpad(a1.mon,2,'0'),'mm'),'Mon')
  from ( select level mon from dual connect by level <= 12 ) a1
 where not exists ( select null
                      from my_table a2
                     where a1.mon between a2.month_from and a2.month_to
                       and upper(a2.eName) = upper('&i_eName') )
 order by mon;

但是,它还返回 9月 10月 11月 12月,除了 Jun < / strong>即可。为此,我同意@ mathguy的评论。