none
SQL Abfrage mit wenn dann RRS feed

  • Frage

  • Hallo allerseits,

    ich verzweifle gerade an folgendem Problem: es soll die Summe der Umsätze (Tabelle 1) aller Kunden (Tabelle 2) ausgegeben werden, deren Vertragslaufzeit (Tabelle 3) im 1. Quartal 2014 endet.

    Soweit so gut... die Vertragslaufzeit soll sich errechnen aus Vertragsbeginn+Laufzeit. Wenn das Ergebnis < 31.12.2014 dann +12 Monate, ist auch dieses Ergebnis < 31.12.2014 dann wieder +12 Monate und zwar solange bis das 1. Quartal 2014 erreicht ist (=true) oder überschritten ist (=false).

    Bis zur Ausgabe des Umsatzes, wenn der Vertrag im entsprechenden Quartal endet habe ich meine Abfrage hinbekommen: DATEADD(month, [Laufzeit], [Vertragsbeginn]) between @Q1_a and @Q1_e aber es fehlt mir der Teil mit +12 +12 usw. bei den älteren Verträgen.

    So in etwa habe ich mir das vorgestellt: if ((DATEADD(month, [Laufzeit], [Vertragsbeginn]))< '2014-01-01', select(DATEADD(month, 12, [Vertragsbeginn]))  else select(DATEADD(month, [Laufzeit], [Vertragsbeginn]))) leider funktioniert es aber nicht...  Ich bin SQL Anfänger, habe mir eigentlich alles selbst beigebracht, daher bitte ich um Gnade... ;)

    Kann mir bitte bitte jemand weiterhelfen?

    Danke im voraus.
    Grüße Marika

    Donnerstag, 23. Januar 2014 18:27

Antworten

  • Hallo Marika, bemühe am besten etwas Datumsarithmetik. Wahrscheinlich musst Du ein paar mal hinschauen, um es zu verstehen, aber es lohnt sich.

    Declare @Vertragsbeginn date= '2010-03-12',
                 @Laufzeit                int = 24;
    
    Select        Dateadd(Month, @Laufzeit, @Vertragsbeginn) as [Ende Erste
    Laufzeit],
                 DATEDIFF(YEAR, Dateadd(Month, @Laufzeit, @Vertragsbeginn),
    getdate()) as [Jahre Differenz Laufzeit Aktuelles Datum],
                 DATEADD(YEAR, DATEDIFF(YEAR, Dateadd(Month, @Laufzeit,
    @Vertragsbeginn), getdate()) , Dateadd(Month, @Laufzeit, @Vertragsbeginn))
    [Vertragsende aktuelles Jahr],
                 DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0) AS [Jahresbeginn],
                 DATEADD(qq,DATEDIFF(qq,0,DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()),
    0)),0) as [First Day Of First Quarter],
                 DATEADD(qq,DATEDIFF(qq,-1,DATEADD(YEAR, DATEDIFF(YEAR, 0,
    GETDATE()), 0)),-1) as [Last Day Of First Quarter]
                 ;

    Damit errechnest Du das Vertragsende-Datum im aktuellen Jahr und kannst das dann in der Abfrage mit

    WHERE <Vertragsende aktuelles Jahr> between <First Day Of First Quarter> and
    <Last Day Of First Quarter>

    relativ einfach weiterverarbeiten.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    • Als Antwort markiert zimtstern2014 Freitag, 24. Januar 2014 14:06
    Freitag, 24. Januar 2014 07:19

Alle Antworten

  • Hi Marika,

    zieh doch Start Datum duch Endatum ab Sollte ein TimeSpan ergeben (bin jetzt kein SQL experte) in Monate umwandel Rechne Modulo 12 und wenn der  kleine gleich 3 ist liegt es im 1. Quatal.

    MFG

    Björn

    Donnerstag, 23. Januar 2014 19:00
  • Hallo Marika,

    etwas verwirrend ist Deine Beschreibung schon. So wie ich Dich verstehe hast Du ein Datum(Vertragsbeginn) und eine Vertragslaufzeit in Monaten(?). Du willst alle Kunden deren Verträge zwischen dem 01.01.14 und dem 31.03.14 enden. Nicht die Kunden deren Vertrag vor dem 01.01.14 oder nach dem 31.03.14 enden.


    DATEADD(month, [Laufzeit], [Vertragsbeginn]) between @Q1_a and @Q1_e

    Aber diese Logik stimmt bei älteren Verträgen nicht? Weil?

    Dieses +12 +12 usw. ist doch meiner Meinung nach nur eine Krücke, kannst Du denn nicht auswerten

    MONTH(vertragsbeginn) -1 between 1 AND 3
    

    Ein Vetrag der am 01.04... beginnt, endet am 31.03.. des Folgejahres, deshalb -1

    Dann brauchst Du nur

    bedingung1 OR bedingung2

    Gruss Uli



    Freitag, 24. Januar 2014 06:53
  • Hallo Marika, bemühe am besten etwas Datumsarithmetik. Wahrscheinlich musst Du ein paar mal hinschauen, um es zu verstehen, aber es lohnt sich.

    Declare @Vertragsbeginn date= '2010-03-12',
                 @Laufzeit                int = 24;
    
    Select        Dateadd(Month, @Laufzeit, @Vertragsbeginn) as [Ende Erste
    Laufzeit],
                 DATEDIFF(YEAR, Dateadd(Month, @Laufzeit, @Vertragsbeginn),
    getdate()) as [Jahre Differenz Laufzeit Aktuelles Datum],
                 DATEADD(YEAR, DATEDIFF(YEAR, Dateadd(Month, @Laufzeit,
    @Vertragsbeginn), getdate()) , Dateadd(Month, @Laufzeit, @Vertragsbeginn))
    [Vertragsende aktuelles Jahr],
                 DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0) AS [Jahresbeginn],
                 DATEADD(qq,DATEDIFF(qq,0,DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()),
    0)),0) as [First Day Of First Quarter],
                 DATEADD(qq,DATEDIFF(qq,-1,DATEADD(YEAR, DATEDIFF(YEAR, 0,
    GETDATE()), 0)),-1) as [Last Day Of First Quarter]
                 ;

    Damit errechnest Du das Vertragsende-Datum im aktuellen Jahr und kannst das dann in der Abfrage mit

    WHERE <Vertragsende aktuelles Jahr> between <First Day Of First Quarter> and
    <Last Day Of First Quarter>

    relativ einfach weiterverarbeiten.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    • Als Antwort markiert zimtstern2014 Freitag, 24. Januar 2014 14:06
    Freitag, 24. Januar 2014 07:19
  • Hallo Björn, danke für deine Antwort, ich probier das mal aus. VG Marika
    Freitag, 24. Januar 2014 10:54
  • Hallo Uli, also ich habe Verträge mit unterschiedlichen Laufzeiten (3, 6, 12, 24, 36... bis 99 MOnate ist alles drin) somit endet ein Vertrag nicht zwingend im gleichen Monat in dem er angefangen hat. Nach Ende der ersten Laufzeit verlängert er sich automatisch um 12 Monate, wenn er nicht gekündigt wird, das Beginn Datum bleibt jedoch bestehen. Deswegen brauche ich Beginn+Laufzeit- wenn das Ergebnis vor dem aktuellen Quartal liegt, dann 12 Moante hinzu, wenn es immer noch in der Vergangenheit ist, dann wieder 12 Monate hinzu, so lange bis das aktuelle Quartal erreicht oder überschritten ist. Wenn es erreicht ist, ist die Bedingung erfüllt, wenn es überschritten ist wird dieser Vertrag ignoriert. Ich hoffe, das ist etwas verständlicher..?

    VG Marika

    Freitag, 24. Januar 2014 11:00
  • Genau dies berücksichtigt die SQL-Variante:

    Declare @Vertragsbeginn date= '2000-03-12',
                            @Laufzeit                                int = 99;
    
    Select                Dateadd(Month, @Laufzeit, @Vertragsbeginn) as [Ende Erste
    Laufzeit],
                            DATEDIFF(YEAR, Dateadd(Month, @Laufzeit, @Vertragsbeginn),
    getdate()) as [Jahre Differenz Laufzeit Aktuelles Datum],
                            DATEADD(YEAR, DATEDIFF(YEAR, Dateadd(Month, @Laufzeit,
    @Vertragsbeginn), getdate()) , Dateadd(Month, @Laufzeit, @Vertragsbeginn))
    [Vertragsende aktuelles Jahr],
                            DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0) AS
    [Jahresbeginn],
                            DATEADD(qq,DATEDIFF(qq,0,DATEADD(YEAR, DATEDIFF(YEAR, 0,
    GETDATE()),
    0)),0) as [First Day Of First Quarter],
                            DATEADD(qq,DATEDIFF(qq,-1,DATEADD(YEAR, DATEDIFF(YEAR, 0,
    GETDATE()), 0)),-1) as [Last Day Of First Quarter]
                            ;

     Wenn Du den verhunzten Zeilenumbruch bereinigt hast, liest es sich auch besser.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    Freitag, 24. Januar 2014 13:18
  • Hi Christoph,

    ich habe folgendes genommen:

    where [Jahre Differenz Laufzeit Aktuelles Datum]>=0 and <Vertragsende aktuelles Jahr> between <First Day Of First Quarter> and <Last Day Of First Quarter>

    Das Ergebnis sieht ganz gut aus, ich denke das passt.

    Vielen lieben Dank! Wünsch dir ein schönes WE
    Marika


    Freitag, 24. Januar 2014 14:06