使用SQL处理日期

时间:2017-05-11 20:02:20

标签: sql oracle

假设有一个帐户,我必须每年都要收取费用。

因此,对于每次收费,会在表格中生成一行,提及其日期。 遗憾的是,由于某种原因,在特定年份未能收取费用,并且该年度没有生成任何行。

所以我的目标是找到错过指控和年份的所有帐户。

1 个答案:

答案 0 :(得分:0)

下面的解决方案会找到缺少付款的年份,但只会在表格中显示付款的年份之间找到。它会查找第一年错过的付款,或者错过未收到付款的付款。 (例如,如果付款应该是从2010年到2016年,并且该表仅显示2012年,2013年,2015年,那么解决方案将找到2014年,但它将找不到2010年,2011年和2016年)。表格中的数据不足以找到错过的付款;此外,如果某个帐户应该有付款,但没有付款曾经,那么该帐户根本不会存在于您的表中,因此该解决方案无法捕获这些帐户。

with
     test_data ( acctno, chargetype, dt ) as (
       select 1, 'xyz', to_date('20-01-2014', 'dd-mm-yyyy') from dual union all
       select 1, 'abc', to_date('20-01-2015', 'dd-mm-yyyy') from dual union all
       select 1, 'xyz', to_date('20-01-2017', 'dd-mm-yyyy') from dual union all
       select 2, 'xyz', to_date('20-01-2015', 'dd-mm-yyyy') from dual union all
       select 2, 'xyz', to_date('20-01-2016', 'dd-mm-yyyy') from dual union all
       select 2, 'xyz', to_date('20-01-2017', 'dd-mm-yyyy') from dual
     )
-- End of test data (not part of the solution)
-- Query begins below this line; use your actual table name instead of "test_data"
select acctno, min_year + level - 1 as yr
from   (
         select   acctno, 
                  min(extract(year from dt)) min_year, 
                  max(extract(year from dt)) max_year
         from     test_data
         group by acctno
       )
where (acctno, min_year + level - 1) not in ( select acctno, extract(year from dt)
                                              from   test_data
                                            )
connect by level <= max_year - min_year + 1
       and prior acctno = acctno
       and prior sys_guid() is not null
;

ACCTNO    YR
------  ----
     1  2016