Kreuztabelle

Hallo,
habe folgende Aufgabe, leider komme ich da nicht weiter, wäre sehr dankbar für die Tipps, muss keine Lösung sein, die nötigsten SQL-Statesments würde ich wohl selber hinbekommen.
Habe eine Tabelle folgender Struktur:
Priorität | Finish_Datum | Dauer
___________________________________
Hoch | 01.01.2003 | 0.5
Hoch | 01.02.2006 | 7
Hoch | 01.02.2006 | 6.7
Mittel | 01.02.2006 | 2
Mittel | 01.02.2006 | 0.2
Niedrig | 01.01.2003 | 2.8
Niedrig | 01.02.2006 | 3.4

Folgendes Ergebniss wird erwartet

Priorität | >0>=1 | >1>=4 |>4>=8 |Summe
__________________________________________
Hoch | 0 | 0 | 2 | 2
Mittel | 1 | 1 | 0 | 2
Niedrig | 0 | 1 | 0 | 1
summe | 1 | 2 | 2 | 5

Wobei die Daten im Zeitraum von 01.01.2006 und 31.03.2006 benötigt werden.
Müssen Hilfstabellen angelegt werden? Welche Mechanismen werden eingesetzt(joins… etc.)
Wäre echt für Hilfe dankbar.
Leider ist die Formatierung grottenschlecht :frowning:

Liebe grüße

hi olga

zunächsteinmal: ein pre-tag wirkt wunder bei der formatierung…

zu deinem problem: ich kenne eine lösung, allerdings funkt die in dieser form nur unter oracle. ob andere db-systeme ähnliche funktionen kennen, weiss ich nicht:

select priorität,
 sum(decode(sign(dauer - 1),1,0,1)) bis1,
 sum(decode(sign(dauer - 1) + (sign(dauer - 4.0000001)\*-1),2,1,0)) bis4,
 sum(decode(sign(dauer - 4) + (sign(dauer - 8.0000001)\*-1),2,1,0)) bis8,
 count(\*) summebis8
 from tabelle
 where dauer 

schaut kompliziert aus und ist es auch: ich brauche eine formel, die 1 ergibt, wenn der wert zwischen zwei bestimmten werten ist und 0 wenn nicht. diese kann ich dann einfach summieren.

das ganze ist natürlich ziemlich quick&dirty und funkt nur, wenn die werte für die dauer nicht allzuviele nachkommastellen haben. aber für dein problem wird es schon reichen...

hinweis: die datumsabfrage funkt nur, wenn dein datumsformat entsprechend eingestellt ist. ansonsten musst du mit to\_date explizit konvertieren.

übrigens: der obige trick funkt auch vorzüglich in excel, z.b. wenn man zeilen nach komplizierten regeln zählen will.

lg
erwin



> Hallo,  
> habe folgende Aufgabe, leider komme ich da nicht weiter, wäre  
> sehr dankbar für die Tipps, muss keine Lösung sein, die  
> nötigsten SQL-Statesments würde ich wohl selber hinbekommen.  
> Habe eine Tabelle folgender Struktur:



    
    
    
    > Priorität | Finish\_Datum | Dauer  
    > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
    > Hoch | 01.01.2003 | 0.5  
    > Hoch | 01.02.2006 | 7  
    > Hoch | 01.02.2006 | 6.7  
    > Mittel | 01.02.2006 | 2  
    > Mittel | 01.02.2006 | 0.2  
    > Niedrig | 01.01.2003 | 2.8  
    > Niedrig | 01.02.2006 | 3.4
    





> Folgendes Ergebniss wird erwartet



    
    
    
    > Priorität | \>0\>=1 | \>1\>=4 |\>4\>=8 |Summe  
    > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
    > Hoch | 0 | 0 | 2 | 2  
    > Mittel | 1 | 1 | 0 | 2  
    > Niedrig | 0 | 1 | 0 | 1  
    > summe | 1 | 2 | 2 | 5
    





> Wobei die Daten im Zeitraum von 01.01.2006 und 31.03.2006  
> benötigt werden.  
> Müssen Hilfstabellen angelegt werden? Welche Mechanismen  
> werden eingesetzt(joins.. etc.)  
> Wäre echt für Hilfe dankbar.  
> Leider ist die Formatierung grottenschlecht :frowning:  
>   
> Liebe grüße

ach ja, erklärung für nicht oracle user

select priorität,
sum(decode(sign(dauer - 1),1,0,1)) bis1,
sum(decode(sign(dauer - 1) + (sign(dauer -
4.0000001)*-1),2,1,0)) bis4,
sum(decode(sign(dauer - 4) + (sign(dauer -
8.0000001)*-1),2,1,0)) bis8,
count(*) summebis8
from tabelle
where dauer

select decode(status,
1, ‚in Arbeit‘,
2, ‚geplant‘,
3, ‚fertig‘,
-1,‚storniert‘,
‚undefiniert‘) statusklar
from aufgaben;

der between-operator entspricht einem "where wert >= a and wert

immer diese blöden tippfehler…

select priorität,
 sum(decode(sign(dauer - 1),1,0,1)) "\>0\>=1",
 sum(decode(sign(dauer - 1) + (sign(dauer - 4.0000001)\*-1),2,1,0)) "\>1\>=4",
 sum(decode(sign(dauer - 4) + (sign(dauer - 8.0000001)\*-1),2,1,0)) "\>4\>=8",
 count(\*) "Summe"
 from tabelle
 where dauer 

Hallo Erwin, danke für die Lösung!
Es funktioniert, bis auf die letzte Zeile in der Ergebniss-Tabelle, da sollte auch die Summe errechnet werden.
Aber das wird wahrscheinlich nicht so einfach sein, da muss man wahrscheinlich solche Sachen wie Dimensionierte Tabellen(Cube-Aufbereitung) verwenden.
Liebe Grüße

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

hi olga

oh schande - nicht fertig gelesen.

du hast recht: die letzte summenzeile wird schwierig. zwei lösungen fallen mir ein, vorausgesetzt du verwendest oracle und sqlplus:

  • sqlplus bietet rudimentäre reporting-funktionen, mit der du spalten aufsummieren kannst. damit klappt es auf jeden fall - allerdings nur innerhalb von sqplus.

  • andere möglichkeit, die immer funkt, auch ohne sqlplus: eine zweites select, mit der nur die summe selected wird und dann eine union darüber. damit das zweite select immer am ende kommt, muss man eine zusätzliche pseudospalte selektieren: im erste select einfach als letzte spalte den fixen wert „1“ und im zweiten den wert „2“. sortiert wird zuerst nach der letzten spalte und dann nach den anderen spalten. nachteil: du hast eben eine zusätzliche spalte, die möglicherweise stört. in sqlplus kannst du diese spalte mit „col xxx noprint“ ausblenden. in anderen programmen geht es vielleicht ähnlich.

hier mal das fertige beispiel:

select priorität,
 sum(decode(sign(dauer - 1),1,0,1)) "\>0\>=1",
 sum(decode(sign(dauer - 1) + (sign(dauer - 4.0000001)\*-1),2,1,0)) "\>1\>=4",
 sum(decode(sign(dauer - 4) + (sign(dauer - 8.0000001)\*-1),2,1,0)) "\>4\>=8",
 count(\*) "Summe",
 '1' sorter
 from tabelle
 where dauer 0\>=1",
 sum(decode(sign(dauer - 1) + (sign(dauer - 4.0000001)\*-1),2,1,0)) "\>1\>=4",
 sum(decode(sign(dauer - 4) + (sign(dauer - 8.0000001)\*-1),2,1,0)) "\>4\>=8",
 count(\*) "Summe",
 '2' sorter
 from tabelle
 where dauer 

wenn die reihenfolge der zeilen (also summe am schluss) unwichtig ist, dann kannst du dir natürlich die pseudospalte und das order-by sparen. in diesem speziellen beispiel würde sogar das sortieren nur nach der ersten spalte ja ausreichen, da "S" nach "N" kommt. wenn die prioritäten frei eingebbar sind, wirst du aber für eine saubere reihenfolge auf jeden fall die pseudospalte brauchen.

wenn man das häufiger braucht und sich die schwellwerte nicht ändern, ist natürlich das anlegen einer view angebracht - man spart sich viel tipparbeit.

erwin

Hallo Erwin,
besten Dank für die Lösung sie funktioniert auf jeden Fall, ich werde mich auf jeden Fall mit dieser Lösung auseinandersetzen, und dann schauen. Leider bin ich schon viel zu Lange aus der Programmierung raus.
Wenn man nur Server(Datenbankserver) administriert gehen viele Kenntnisse irgendwann verloren.
Wir setzen hauptsächlich Oracle ein, aber SQLServer wird auch noch genutzt.
Liebe grüße