# SQL Problem mit Count + Group By



## Jens81 (15. Mrz 2010)

Hallo zusammen,

aus einer Java Anwendung schicke ich SQL Abfragen zum Zählen von Werten auf eine Datenbank.

Jetzt möchte ich aber z.B. nur ungern 5 einzelne Abfragen abschicken:

```
String abfrage1 = SELECT COUNT(1) FROM tab1 as alt, tab2 as neu WHERE alt.KDNR = neu.KDNR AND alt.rank = 1 AND neu.rank = 1;
String abfrage2 = SELECT COUNT(1) FROM tab1 as alt, tab2 as neu WHERE alt.KDNR = neu.KDNR AND alt.rank = 1 AND neu.rank = 2;
String abfrage3 = SELECT COUNT(1) FROM tab1 as alt, tab2 as neu WHERE alt.KDNR = neu.KDNR AND alt.rank = 1 AND neu.rank = 3;
String abfrage4 = SELECT COUNT(1) FROM tab1 as alt, tab2 as neu WHERE alt.KDNR = neu.KDNR AND alt.rank = 1 AND neu.rank = 4;
String abfrage5 = SELECT COUNT(1) FROM tab1 as alt, tab2 as neu WHERE alt.KDNR = neu.KDNR AND alt.rank = 1 AND neu.rank = 5;
```

sondern eine Abfrage mit Group By verwenden:

```
String abfrage = SELECT COUNT(1) FROM tab1 as alt, tab2 as neu WHERE alt.KDNR = neu.KDNR AND alt.rank = 1 AND neu.rank < 6 GROUP BY neu.rank;
```

Problem ist nun, dass, falls in einer Gruppe 0 Werte vorkommen, nicht 5 Ergebnisse, sondern nur 4 zurückgeliefert werden. Ist es möglich, auch eine 0 zurückzubekommen? Für eine Weiterverarbeitung wäre es nötig / hilfreich, wenn die Rückgabe immer die gleiche Form / Struktur hat.

Ich weiß, es ist mehr eine SQL Frage... hoffe, dass sich trotzdem der ein oder andere hier damit besser auskennt.

Danke und Gruß,
Jens


----------



## SlaterB (15. Mrz 2010)

eine Idee:
du bräuchtest eine Dummy-Tabelle mit Einträgen 1-n,
dann ein left join darüber

-----

so wie du die Abfrage bisher hast, ist die Reihenfolge nicht gesichert, noch ein ORDER BY?


----------



## Gast2 (15. Mrz 2010)

Guck dir das mal an: SQL COUNT( NULLIF( .. ) ) Is Totally Awesome


----------



## Jens81 (15. Mrz 2010)

Stimmt, das ORDER BY fehlte natürlich noch. Die Lösung mit der Dummy Tabelle ist möglich, aber nicht wirklich schön...



fassy hat gesagt.:


> Guck dir das mal an: SQL COUNT( NULLIF( .. ) ) Is Totally Awesome



Ich glaube, dass hilft hier leider nicht weiter. Das Problem ist ja nicht, dass Missing Values nicht mitgezählt werden, sondern dass aufgrund der WHERE Bedingung (in bestimmten Konstellationen) keine 5 Gruppen zustande kommen.

Wenn es für jede Gruppe Treffer gibt, sieht das Ergebnis z.B. so aus (via Group by Abfrage):
987985
200341
189112
98552
19244

Gibt es aber nicht immer in jeder Gruppe Treffer, könnte auch mal sowas bei raus kommen:
1200921
378871
10923

Nun weiß ich nicht, welches die 2 leeren Gruppen sind...


----------



## Gast2 (15. Mrz 2010)

Dann gib doch die Gruppe mit aus:


```
String abfrage = SELECT neu.rank, COUNT(1) FROM tab1 as alt, tab2 as neu WHERE alt.KDNR = neu.KDNR AND alt.rank = 1 AND neu.rank < 6 GROUP BY neu.rank;
```

Das Problem ist wirklich das da schon viel wegoptimiert wird... Kannst mit Subselects oder UNION arbeiten wenn du eine feste Menge an Gruppen hast. - Dann halt für jeden Subselect gucken ob es eine Ergebniss hat sonst 0 setzen.


----------



## Jens81 (15. Mrz 2010)

So wie es ausschaut, werde ich mir die Gruppe mit ausgeben, die leeren / fehlenden Datensätze im Programm ergänzen und die Ergebnisse dann zur Verarbeitung weiterreichen. Scheint dann wohl die performanteste Lösung zu sein.

Hatte gehofft, dass es noch eine (einfache) Möglichkeit gibt, alles im SQL Statement zu lösen. Vielen Dank für eure Ratschläge!


----------



## Jens81 (15. Mrz 2010)

Eine ergänzende Frage habe ich allerdings noch:

Wenn man alt.rank nicht nur bei 1 belassen möchte, sondern diesen auch bis 5 hochzählt, ist das in einer Abfrage machbar? (= 25 Ergebnisse, wenn alle Gruppen vorhanden)

Gibts sowas wie eine Schleife? oder via Subquery?


----------



## SlaterB (15. Mrz 2010)

ist mir bisher nicht begegnet, bin immer noch für Dummy-Tabelle,
dort ein Join, schon hast du 25 Elemente voreingestellt,
wobei ich das nur theoretisch so sehe,
4 joins teils verschiedener Arten, bestimmt ne Menge zu basteln falls es überhaupt geht


----------

