1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  2. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

CASE-Anweisung nach where?

Dieses Thema im Forum "Oracle" wurde erstellt von Sonnfan, 5 Januar 2011.

  1. Sonnfan

    Sonnfan Benutzer

    Hallo liebe Community,

    ich möchte in einer Daten der letzten drei vollen Monate darstellen. In der Tabelle gibt es auch eine Spalte "MONTH", in der zu den jeweiligen Datensätzen eben die Zahlen 1-12 stehen.

    Weil das aber über den Jahreswechsel Problematisch wird, da ich ja auch noch Daten aus dem vorherigen und gleichzeitig aus dem aktuellen Jahr (z.b. will ich November, Dezember, Januar angezeigt bekommen, wenn ich ich Februar schaue) darstellen muss, hab ich mir gedacht, lös ich das über Case-Klauseln.

    Da ich noch nie Case-Anweisungen gebraucht habe, habe ich mir jetzt mal angeschaut, wie das eigentlich geht. Dabei stellt sich mir zuerst schon die Frage, ob ich Case-Anweisungen auch in der where-Bedingung nutzen kann, und nicht nur in den Select-Anweisungen.

    Ich hatte mir etwas in der Art vorgestellt:
    Code:
    SELECT ...
    FROM ...
    WHERE ...
    AND 
    
    CASE to_char(add_months(trunc(sysdate,'MM'),-1),'MM')
    
    WHEN '12'
    THEN "YEAR" = to_char(add_months(trunc(sysdate,'MM'),-1),'YYYY') AND "MONTH" > '9'
    
    WHEN '1'
    THEN ("YEAR" = to_char(add_months(trunc(sysdate,'MM'),-1),'YYYY') AND "MONTH" > '10')
    OR ("YEAR" = to_char(add_months(trunc(sysdate,'MM'),-0),'YYYY') AND "MONTH" = '1')
    
    END
    
    order by ...
    
    (etc, ein paar Case-Bedingungen fehlen da schon noch, nur als Beispiel)

    Natürlich funktioniert das so nicht.

    Deshalb meine Frage:
    1. Geht das an der Stelle überhaupt?
    2. Wenn ja, was ist an dem Code falsch?

    Viele Grüße,
    Sonnfan
     
  2. Sonnfan

    Sonnfan Benutzer

    AW: CASE-Anweisung nach where?

    (Wo ist der Edit-Button?!)

    Inzwischen hab ich aber auf englischsprachigen Seiten herausgefunden, dass das anscheinend irgendwie aussehen muss alá

    Code:
    "MONTH" = CASE
    WHEN to_char(add_months(trunc(sysdate,'MM'),-1) = '1' THEN >'10' OR '1'
    WHEN to_char(add_months(trunc(sysdate,'MM'),-1) = '2' THEN >'11' OR '2'
    WHEN (to_char(add_months(trunc(sysdate,'MM'),-1) > '3' AND (to_char(add_months(trunc(sysdate,'MM'),-1) <=12)
    THEN >to_char(add_months(trunc(sysdate,'MM'),-4),'YYYY')
    
    Da probier ich grad dran rum. Weniger erfolgreich. =/

    Edit: Bei dem Beitrag ist der Ändern-Button da, oben nicht...
     
  3. Sonnfan

    Sonnfan Benutzer

    AW: CASE-Anweisung nach where?

    Hmm, inzwischen hab ich Testweise mit
    Code:
    select Kategorien, Month
    from V_TICKETS_CL_NAGIOS_AVG_MONTH
    where "MONTH" = 
    CASE 
    when '1' = '1' then '11'
    when '1' = '2' then '12'
    END
    
    sinnvolle Ergebnisse erhalten, nur mit dem to_char geht es nicht...

    Da kommt dann immer Die Fehlermeldung im Orcacle SQL Developer ist immer nur "SQL command not properly ended" in der Zeile mit AND "MONTH" = CASE to_char(add_months(trunc(sysdate,'MM'),-1) und somit nicht sehr hilfreich. =/

    Möglich, dass solche Ausdrücke an der Stelle nicht funktionieren...
     
  4. Sonnfan

    Sonnfan Benutzer

    AW: CASE-Anweisung nach where?

    Damit funktioniert es nun:
    Code:
    SELECT ...
    FROM ...
    WHERE "MONTH" = CASE
    
    WHEN to_char(add_months(trunc(sysdate,'MM'),-1),'MM') = '12' THEN '10'  -- OR '11' OR '12'
    WHEN to_char(add_months(trunc(sysdate,'MM'),-1),'MM') = '01' THEN '11'  -- OR '12' OR '01'
    --ELSE >(to_char(add_months(trunc(sysdate,'MM'),-4),'MM'))
    END
    
    order by KATEGORIEN, Month
    
    Nun muss ich nur noch das Auskommentierte (--) zum funktionieren bringen, weil das geht immernoch nicht. xD Die Mehrfachauswahl z.B.
     
  5. Sonnfan

    Sonnfan Benutzer

    AW: CASE-Anweisung nach where?

    Nochmal zurück zu dem Thema: Kann mir jemand die Syntax sagen, mit der ich nach einer Bedingung mehrere mögliche Werte zulassen kann, sprich dass bei der ersten Bedingung im Post drüber z.B. alle Monate mit 10, 11 oder 12 gezeigt werden?
     
  6. Charly

    Charly Datenbank-Guru

    AW: CASE-Anweisung nach where?

    Hallo Sonnfan,

    OR-Verknüfungen gehen da nicht!

    Da bis jetzt noch niemand auf deine Frage geantwortet hat stelle ich meine Lösung einfach mal Online.

    Da ich über keine Oracle installation verfüge, habe ich meinen MS SQL-Server genommen.

    Das übertragen auf PL/SQL sollte aber nicht das Problem sein.

    Zuerst mal eine Spieltabelle bauen:

    Code:
     
    CREATE TABLE Datum
    (
     Monat nvarchar(2)
    , Jahr nvarchar(4)
    )
    
    Tabelle mit Spieldaten füllen:

    Code:
     
    insert into Datum (Monat, Jahr) Values('01','2010')
    insert into Datum (Monat, Jahr) Values('02','2010')
    insert into Datum (Monat, Jahr) Values('03','2010')
    insert into Datum (Monat, Jahr) Values('04','2010')
    insert into Datum (Monat, Jahr) Values('05','2010')
    insert into Datum (Monat, Jahr) Values('06','2010')
    insert into Datum (Monat, Jahr) Values('07','2010')
    insert into Datum (Monat, Jahr) Values('08','2010')
    insert into Datum (Monat, Jahr) Values('09','2010')
    insert into Datum (Monat, Jahr) Values('10','2010')
    insert into Datum (Monat, Jahr) Values('11','2010')
    insert into Datum (Monat, Jahr) Values('12','2010')
    insert into Datum (Monat, Jahr) Values('01','2011')
    insert into Datum (Monat, Jahr) Values('02','2011')
    insert into Datum (Monat, Jahr) Values('03','2011')
    insert into Datum (Monat, Jahr) Values('04','2011')
    insert into Datum (Monat, Jahr) Values('05','2011')
    insert into Datum (Monat, Jahr) Values('06','2011')
    insert into Datum (Monat, Jahr) Values('07','2011')
    insert into Datum (Monat, Jahr) Values('08','2011')
    insert into Datum (Monat, Jahr) Values('09','2011')
    insert into Datum (Monat, Jahr) Values('10','2011')
    insert into Datum (Monat, Jahr) Values('11','2011')
    insert into Datum (Monat, Jahr) Values('12','2011')
    
    Jetzt noch die Abfrage:

    Wie ich aus deinen Beiträgen sehen konnte hat die Tabelle eine Monats- und eine Jahres-Spalte und du willst alle Datensätze des aktuellen Monats und der beiden letzten Monate filtern. Wenn du deine Abfrage im Januar oder Februar ausführst hättest du gerne die Daten von November und Dezember des Vorjahres mit drin.

    Im Grunde habe ich für die letzten 3 Monate in der WHERE-Bedingung jedesmal das gleiche gemacht.

    1) Vergleiche Die Monatsspalte mit dem aktuellen Monat
    UND
    2a) Vergleiche das Jahr
    2b) Wenn der aktuelle Monat '01' ist
    2b) Vergleich die Monatsspalte mit '11' und '12'
    2c) Wenn der Vergleich positiv ist setzt das Jahr für den Vergleich um eins zurück andernfalls setzte das aktuelle Jahr als Vergleich ein

    Für die zweite case Punkt 2b) den Monat auf Monat ist '02' gesetzt.

    Und dann nochmal die Punkte 1) bis 2c) für den aktuellen Monat - 1 und -2 wiederholen.


    Code:
    SELECT *
    FROM Datum
    WHERE Monat = MONTH(GETDATE())
    AND Jahr = CASE 
     WHEN Month(Getdate()) = '01' THEN
      CASE 
       WHEN Monat = '11' THEN YEAR(Getdate()) - 1
       WHEN Monat = '12' THEN YEAR(Getdate()) - 1
       ELSE YEAR(Getdate())
      END
     WHEN Month(Getdate()) = '02' THEN
      CASE 
       WHEN Monat = '12' THEN YEAR(Getdate()) - 1
       ELSE YEAR(Getdate()) 
      END
    END
    OR Monat = MONTH(DATEADD(MONTH,-1,GETDATE()))
    AND Jahr = CASE 
     WHEN Month(Getdate()) = '01' THEN
      CASE 
       WHEN Monat = '11' THEN YEAR(Getdate()) - 1
       WHEN Monat = '12' THEN YEAR(Getdate()) - 1
       ELSE YEAR(Getdate())
      END
     WHEN Month(Getdate()) = '02' THEN
      CASE 
       WHEN Monat = '12' THEN YEAR(Getdate()) - 1
       ELSE YEAR(Getdate()) 
      END
    END
    OR Monat = MONTH(DATEADD(MONTH,-2,GETDATE()))
    AND Jahr = CASE 
     WHEN Month(Getdate()) = '01' THEN
      CASE 
       WHEN Monat = '11' THEN YEAR(Getdate()) - 1
       WHEN Monat = '12' THEN YEAR(Getdate()) - 1
       ELSE YEAR(Getdate())
      END
     WHEN Month(Getdate()) = '02' THEN
      CASE 
       WHEN Monat = '12' THEN YEAR(Getdate()) - 1
       ELSE YEAR(Getdate()) 
      END
    END
    

    Das Problem hat mich gereizt und ich hoffe dir mit meiner Lösung geholfen zu haben.

    Gruß Charly

    PS: Leider kann ich dir die Lösung hier nur mit T-SQL schreiben. Ich setzt mir in den nächsten Monaten mal einen Oracle auf. Dann gibts auch Lösungen in PL/SQL.
     
  7. Sonnfan

    Sonnfan Benutzer

    AW: CASE-Anweisung nach where?

    Coole Sache, danke, ich werds morgen auf Arbeit gleich mal ausprobieren. Und du hast recht, da sind schon ein paar Klauseln drin, die ich auf die passende Syntax umändern muss, aber auf den ersten Blick sollte das schon passen. =)

    Ich meld mich dann nochmal dazu, und vielen Dank für deine Mühe!

    Liebe Grüße,
    Sonnfan
     
  8. Sonnfan

    Sonnfan Benutzer

    AW: CASE-Anweisung nach where?

    So, bin grad dran, hab auch schon eine funktionierende Syntax, nur die Ergebnisse sind 0. xD

    Gib mir bitte kurz eine Nachhilfe in T-SQL.
    Was genau macht:
    Code:
    MONTH(DATEADD(MONTH,-1,GETDATE()))
    Gibt mir das den Vormonat? Wohl eher nicht, denn beim Jahr machst du ja
    Code:
    YEAR(Getdate()) - 1
    Das wird wohl die Syntax sein, die den Monat/Jahr vorher ausgibt.

    Also was genau bezweckt der erste Code? =)

    Viele Grüße,
    Sonnfan

    Edit: Ach, ich seh grad, du schreibst "2c) Wenn der Vergleich positiv ist setzt das Jahr für den Vergleich um eins zurück andernfalls setzte das aktuelle Jahr als Vergleich ein". Meinst du das damit?

    Weiß jetzt nicht genau, wie ich das mit Oracle SQL umsetze... "Zurücksetzen" kann man doch nur Variablen, dachte ich.
     
  9. Charly

    Charly Datenbank-Guru

    AW: CASE-Anweisung nach where?

    Hallo Sonnfan,

    YEAR(Getdate()) spuckt 2011 aus

    2011 - 1 = 2010

    DATEADD(MONTH,-1,GETDATE()) spuckt das Aktuelle Datum minus einem Monat aus

    MONTH(DATEADD(MONTH,-1,GETDATE())) ergibt also den Vormonat.

    Wenn du von Heute GETDATE() = 2011-01-17 11:59:34.637 ausgehst
    Minus einem Monat DATEADD(MONTH,-1,GETDATE()) = 2010-12-17 12:00:49.727
    und dann die Monatszahl zurückgibst MONTH(DATEADD(MONTH,-1,GETDATE()))

    Erhälst du 12

    bei '-2' erhälst du 11

    Gruß Charly
     
  10. Sonnfan

    Sonnfan Benutzer

    AW: CASE-Anweisung nach where?

    Danke! Warum kann man das in der Sprache dann nicht auch gleich mit: MONTH(GETDATE()) -1 lösen? Das war es, was mich durcheinander gebracht hat, weil mit dem Jahr scheint es ja auch einfach zu gehen...

    In Oracle wäre das dementsprechend:
    Code:
    OR Month = to_char(add_months(trunc(sysdate,'MM'),-1),'MM')
    (
    Code:
    select to_char(add_months(trunc(sysdate,'MM'),-1),'MM') from dual
    = 12)

    Das hab ich und das scheint soweit ja auch stimmig zu sein, nur leider bekomm ich als Ergebnis nur ne leere Tabelle. Aber das muss ich irgendwie alleine hinbiegen. =)
     
  11. Charly

    Charly Datenbank-Guru

    AW: CASE-Anweisung nach where?

    Hallo Sonnfan,

    MONTH liefert einen Integer-Wert zurück und wenn ich für Januar rechne erhalte ich nicht 12 sondern 0.

    Gruß Charly
     
  12. Sonnfan

    Sonnfan Benutzer

    AW: CASE-Anweisung nach where?

    So, habe jetzt eine funktionierende Version.

    Erst musste ich den Code noch dahingehend ändern, als dass ich gerne die letzten 3 vollen Monate wollte, den aktuellen noch nicht mit.
    Dann hab ich die Syntax noch etwas vereinfacht.

    Sieht bei mir nun so aus:
    Code:
    SELECT...
    FROM ...
    
    WHERE "MONTH" = to_char(add_months(trunc(sysdate,'MM'),-1),'MM')
    AND "YEAR" = CASE 
     WHEN to_char(add_months(trunc(sysdate,'MM'),-0),'MM') = '01' THEN to_char(add_months(trunc(sysdate,'YYYY'),-1),'YYYY')
     ELSE to_char(add_months(trunc(sysdate,'YY'),-0),'YYYY')
    END
    
    OR Month = to_char(add_months(trunc(sysdate,'MM'),-2),'MM')
    AND Year = CASE 
     WHEN to_char(add_months(trunc(sysdate,'MM'),-0),'MM') = '01' THEN to_char(add_months(trunc(sysdate,'YYYY'),-1),'YYYY')
     WHEN to_char(add_months(trunc(sysdate,'MM'),-0),'MM') = '02' THEN to_char(add_months(trunc(sysdate,'YYYY'),-1),'YYYY')
     ELSE to_char(add_months(trunc(sysdate,'YY'),-0),'YY')
    END
    
    OR Month = to_char(add_months(trunc(sysdate,'MM'),-3),'MM')
    AND Year = CASE 
     WHEN to_char(add_months(trunc(sysdate,'MM'),-0),'MM') = '01' THEN to_char(add_months(trunc(sysdate,'YYYY'),-1),'YYYY')
     WHEN to_char(add_months(trunc(sysdate,'MM'),-0),'MM') = '02' THEN to_char(add_months(trunc(sysdate,'YYYY'),-1),'YYYY')
     WHEN to_char(add_months(trunc(sysdate,'MM'),-0),'MM') = '03' THEN to_char(add_months(trunc(sysdate,'YYYY'),-1),'YYYY')
     ELSE to_char(add_months(trunc(sysdate,'YY'),-0),'YY')
    END
    
    
    order by Kategorien,Year, Month
    Wobei im Januar (in Oracle)
    to_char(add_months(trunc(sysdate,'MM'),-0),'MM') = 01
    to_char(add_months(trunc(sysdate,'MM'),-1),'MM') = 12
    to_char(add_months(trunc(sysdate,'YYYY'),-0),'YYYY') = 2011
    to_char(add_months(trunc(sysdate,'YYYY'),-1),'YYYY') = 2010

    Viele Grüße,
    Sonnfan
     
  13. Charly

    Charly Datenbank-Guru

    AW: CASE-Anweisung nach where?

    Na dann bis zum nächsten mal.

    Bis dahin bin ich bestimmt auch Besitzter eines Oracle-Servers.:D

    Gruß Charly
     
Die Seite wird geladen...
Ähnliche Themen
  1. Kautzer
    Antworten:
    5
    Aufrufe:
    887

Diese Seite empfehlen