CASE-Anweisung nach where?

Sonnfan

Benutzer
Beiträge
11
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
 
Werbung:

Sonnfan

Benutzer
Beiträge
11
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...
 

Sonnfan

Benutzer
Beiträge
11
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...
 

Sonnfan

Benutzer
Beiträge
11
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.
 

Sonnfan

Benutzer
Beiträge
11
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?
 

Charly

Datenbank-Guru
Beiträge
306
AW: CASE-Anweisung nach where?

Hallo Sonnfan,

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?

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.
 

Sonnfan

Benutzer
Beiträge
11
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
 

Sonnfan

Benutzer
Beiträge
11
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.
 

Charly

Datenbank-Guru
Beiträge
306
AW: CASE-Anweisung nach where?

Hallo Sonnfan,

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

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
 

Sonnfan

Benutzer
Beiträge
11
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. =)
 

Charly

Datenbank-Guru
Beiträge
306
AW: CASE-Anweisung nach where?

Hallo Sonnfan,

Warum kann man das in der Sprache dann nicht auch gleich mit: MONTH(GETDATE()) -1 lösen?

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

Gruß Charly
 

Sonnfan

Benutzer
Beiträge
11
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
 
Werbung:

Charly

Datenbank-Guru
Beiträge
306
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
 
Oben