Entwickler-Ecke

Datenbanken - Generelle SQL Frage zu COUNT


pesi - Mi 23.02.11 10:40
Titel: Generelle SQL Frage zu COUNT
Hallo,
ich würde mich mal eher als Anfänger im Bereich SQL sehen (der Standard klappt so einigermaßen) und nun bin ich auf der Suche nach einer Lösung für ein komplexeres (???) Problem:

Nehmen wir mal einfach mal eine Tabelle mit folgenden Feldern:

ID (unique)
WERT (Integer)

Das normale Zählen mache ich dann so " Select Count(ID) from Tabelle "
oder auch mal für bestimmte Werte " Select Count(ID) from Tabelle where ID>'40' "

Soweit so einfach... jetzt würde ich aber gerne zählen bei wievielen Datensätzen WERT>40 ist und bei wievielen WERT<40 ist. Also mal ins unreine geschrieben ein "Count(where ID>'40')" und ein Count(where ID<'40') (JA, is natürlich von der Syntax her kompletter Humbug, sollte nur der näeheren Erklärung dienen!).

Bekomme ich sowas in einem Select Statement aber überhaupt hin???
Danke & Gruß


jasocul - Mi 23.02.11 10:48

Auf die Schnelle würde ich es mit diesem Ansatz versuchen:

SQL-Anweisung
1:
2:
3:
Select count(id), sign(wert-40)
from Tabelle
group by sign(wert-40)


pesi - Mi 23.02.11 14:47

Hi Jasoucul,
ist auf jeden Fall schon mal eine sehr interessante Idee! Werde ich an anderer Stelle bestimmt nochmal gut brauchen können! Danke dafür!

Im Bezug auf mein Problem bringt mich das allerdings erst mal nicht weiter, da ich beide Ergebnisse ja gerne in einer Ausgabezeile hätte, so habe ich sie in unterschiedlichen Zeilen.

Ziel des ganzen ist eigentlich, und das hätte ich vielleicht erwähnen sollen, ein Verhältnis der Werte<40 zu den Werten>40 zu erhalten. (also quasi "Werte<40" / "Werte>40")
DAS bekomme ich aber mit Deinem Ansatz erst mal nicht hin :-(

Gruß Peter

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

...oder doch????


BenBE - Mi 23.02.11 15:05

Man kann auch


SQL-Anweisung
1:
2:
3:
4:
5:
SELECT 
    SUM(IF(Wert<40,1,0)) AS Foo, 
    SUM(IF(Wert>40,1,0)) AS Bar,
    COUNT(id) AS Baz
FROM Tabelle


machen. Aus Baz - Bar - Foo bekommt man dann, wieviele genau 40 sind. UND es steht auf einer Zeile :P


Narses - Mi 23.02.11 15:09

Moin!

@user profile iconBenBE: nette Idee, ich hätte das so gemacht:

SQL-Anweisung
1:
SELECT COUNT(*) AS cnt, (wert > 40AS is40 FROM table GROUP BY is40                    

user profile iconpesi hat folgendes geschrieben Zum zitierten Posting springen:
Im Bezug auf mein Problem bringt mich das allerdings erst mal nicht weiter, da ich beide Ergebnisse ja gerne in einer Ausgabezeile hätte, so habe ich sie in unterschiedlichen Zeilen.

Ziel des ganzen ist eigentlich, und das hätte ich vielleicht erwähnen sollen, ein Verhältnis der Werte<40 zu den Werten>40 zu erhalten. (also quasi "Werte<40" / "Werte>40")
Das wirst du AFAIK auch mit einem Statement nicht hinkriegen. :? Hier müsste man ja nochmal nach der Aggregatfunktion rechnen... :nixweiss:

cu
Narses


BenBE - Mi 23.02.11 15:20

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Moin!

@user profile iconBenBE: nette Idee, ich hätte das so gemacht:

SQL-Anweisung
1:
SELECT COUNT(*) AS cnt, (wert > 40AS is40 FROM table GROUP BY is40                    

user profile iconpesi hat folgendes geschrieben Zum zitierten Posting springen:
Im Bezug auf mein Problem bringt mich das allerdings erst mal nicht weiter, da ich beide Ergebnisse ja gerne in einer Ausgabezeile hätte, so habe ich sie in unterschiedlichen Zeilen.

Ziel des ganzen ist eigentlich, und das hätte ich vielleicht erwähnen sollen, ein Verhältnis der Werte<40 zu den Werten>40 zu erhalten. (also quasi "Werte<40" / "Werte>40")
Das wirst du AFAIK auch mit einem Statement nicht hinkriegen. :? Hier müsste man ja nochmal nach der Aggregatfunktion rechnen... :nixweiss:

cu
Narses


Wie jetzt, geht nicht in einem Statement?


SQL-Anweisung
1:
2:
3:
4:
5:
6:
@r := SELECT 
    SUM(IF(Wert<40,1,0)) AS Foo, 
    SUM(IF(Wert>40,1,0)) AS Bar,
    COUNT(id) AS Baz
FROM Tabelle;
SELECT Foo, Bar, Baz, Foo/Bar AS Quo FROM @r


ODER auch direkt:


SQL-Anweisung
1:
2:
3:
4:
5:
SELECT Foo, Bar, Baz, Foo/Bar AS Quo FROM (SELECT 
    SUM(IF(Wert<40,1,0)) AS Foo, 
    SUM(IF(Wert>40,1,0)) AS Bar,
    COUNT(id) AS Baz
FROM Tabelle)


(Beides ungetestet, aber sollte passen.


jasocul - Mi 23.02.11 15:38


SQL-Anweisung
1:
2:
3:
Select * from
(Select count(id) as ge40 from tabelle where wert >= 40),
(Select count(id) as lt40 from tabelle where wert < 40)

Funktioniert bei mir auf Oracle ohne Probleme :wink:


pesi - Mi 23.02.11 15:53

Hui... ich komme ja kaum mit dem Testen der Vorschläge nach, geschweige denn komme ich zum Antworten ;-)

BenBE: Also, dieses SUM(IF(.....)) Gedöns war mit unbekannt und ist für mich [quote]eine echt super Information UND natürlich hilft sie mir auch exakt bei meinem Problem. Da kann ich am Einfachsten mit arbeiten und weiter gruppieren und rechnen und all sowas! SUPER - DANKE!

Jasocul: Deine Lösung funktioniert prinzipiell auch unter MySQL (fehlt nur noch ein AS...), ist auf jeden Fall auch eine tolle Sache die ich noch nicht kannte, ist mir aber eher zu kompliziert wenn ich noch weitere Where-Clauses einfügen will (die müsste ich ja dann mehrfach einfügen (nehme ich mal an). Egal, trotzdem WIEDER WAS GELERNT - DANKE!

Vielen Dank Euch Allen - Hätte gar nicht gedacht, dass ich soooo schnell eine Lösung bekomme! Großartig!

GrußPeter


Narses - Mi 23.02.11 16:07

Moin!

user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
Wie jetzt, geht nicht in einem Statement?
Geht nicht in einem SELECT-Statement, wäre korrekt gewesen. :nixweiss: ;)

cu
Narses


jasocul - Mi 23.02.11 16:20

@pesi:
Oracle ist da nicht so empfindlich, was das "as" betrifft. 8)