2017-05-11 5 views
-2

Sagen wir, es gibt ein Konto, auf dem ich jedes Jahr bis zum Datum eine Gebühr erheben muss.Arbeiten mit Daten mit SQL

Für jede anfallende Gebühr wird in der Tabelle eine Zeile generiert, in der das Datum angegeben wird. Leider wird aus irgendeinem Grund eine Gebühr in einem bestimmten Jahr verpasst und für dieses Jahr wird keine Zeile generiert.

Also mein Ziel ist es, alle diejenigen Konten zu finden, für die die Ladung verpasst wurde und ihr Jahr.

+1

Was ist die Struktur Ihrer Tabelle, und was ist Ihre aktuelle Abfrage, die nicht funktioniert? –

+0

FNR chargetype Datum 1 xyz 20-01-2014 1 abc 20-01-2015 1 xyz 20-01-2017 2 xyz 20-01-2015 2 xyz 20-01-2016 2 xyz 20-01 -2017 –

+0

** [Bearbeiten] ** Ihre Frage und fügen Sie einige Beispieldaten und die erwartete Ausgabe basierend auf diesen Daten. [** Formatierter Text **] (http://stackoverflow.com/help/formatting) bitte, [keine Screenshots] (http://meta.stackoverflow.com/questions/285551/why-may-i-not -upload-images-of-code-auf-so-wenn-eine Frage zu stellen/285557 # 285557). Veröffentlichen Sie keinen Code oder zusätzliche Informationen in Kommentaren –

Antwort

0

Die folgende Lösung findet Jahre mit fehlenden Zahlungen, aber nur zwischen Jahren, die Zahlungen in Ihrer Tabelle anzeigen. Es wird nicht finden Zahlungen im ersten Jahr verpasst, oder verpasste Zahlungen, die nie von Zahlungen gefolgt wurden, die erhalten wurden. (Wenn zum Beispiel die Zahlungen von 2010 bis 2016 gewesen sein sollten und die Tabelle nur 2012, 2013, 2015 zeigt, wird die Lösung 2014 finden, aber 2010, 2011 und 2016 nicht). Die Daten in Ihrer Tabelle reichen nicht aus, um diese verpassten Zahlungen zu finden. Wenn ein Konto Zahlungen hatte, aber keine Zahlungen jemals getätigt wurden, dann wird dieses Konto in Ihrer Tabelle überhaupt nicht vorhanden sein, sodass die Lösung keine Möglichkeit hat, diese Konten abzufangen.

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 
+0

Kudos für eine detaillierte Antwort auf eine unzureichende Frage. – unleashed