PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : min/max/avg einer gruppierten Summe



Gremlin
03.12.2008, 15:56
Ich steh mal wieder vor einem Problem :wink:




Tabelle: verlosung

uid | von | bis
----+-------+-----
1 | 0 | 100
1 | 101 | 203


So ich möchte nun von jedem User die Punkte, Punkte ist die Differenz aus von und bis, folgende Abfrage hab ich dafür gemacht:


SELECT
COUNT(*) AS teilnehmer,
SUM(bis-von) AS gesamt,
MIN(bis-von) AS min,
MAX(bis-von) AS max,
AVG(bis-von) AS avg
FROM
verlosung
GROUP BY
uid
LIMIT 1

Das sollte theoretisch folgendes ausgeben:

teilnehmer = 1
gesamt = 202
min = 202
max = 202
avg = 202

Ausgeben tut es jedoch:

teilnehmer = 2
gesamt = 202
min = 100
max = 102
avg = 101

Also das GROUP BY findet hier wohl keine Anwendung *grübel*

Sebmaster
03.12.2008, 16:16
Zu dem COUNT() kann ich ja Stellung nehmen:

COUNT zählt bei GROUP BY nicht mehr die gesamten Zeilen einer Tabelle, sondern nur noch die Zeilen innerhalb einer Gruppe:rolleyes:

Mfg
Sebmaster

Gremlin
03.12.2008, 16:24
COUNT zählt bei GROUP BY nicht mehr die gesamten Zeilen einer Tabelle, sondern nur noch die Zeilen innerhalb einer Gruppe:rolleyes:
Das ist es doch was ich möchte *grübel* ein User soll nicht 2x als Teilnehmer gelten, sondern nur 1x *think*

Sebmaster
03.12.2008, 16:28
Das ist es doch was ich möchte *grübel* ein User soll nicht 2x als Teilnehmer gelten, sondern nur 1x *think*

Es wird trotzdem nur innerhalb einer Gruppe gesucht.

Pro Gruppe wird dir eine Zeile ausgegeben, die dir alle Zeilen INNERHALB der Gruppe zählt.

=> COUNT zählt nicht die Groups, sondern die Zeilen innerhalb der Groups:der:

Mfg
Sebmaster

VMS1
03.12.2008, 19:51
Also ich verstehe eine Sache nicht


Das sollte theoretisch folgendes ausgeben:

teilnehmer = 1
gesamt = 202
min = 202
max = 202
avg = 202

Warum denn das?

SUM(bis-von) :
SUM(303-101) = 202 Das ist soweit noch klar.

MIN(bis-von) = 202??? MIN sucht den Datensatz ,mit dem kleinsten Spalten-Wert heraus. Und das halt innerhalb der betroffenen Datensätze von GROUP BY. MAX und AVG macht im Prinzip genau das gleiche.

Ich spinn das mal weiter, um zu schauen, ob ich, das, was du haben möchtest, richtig verstehe :

---------------------
| uid | von | bis |
---------------------
| 1 | 0 | 100 |
| 1 | 101 | 203 |
| 2 | 30 | 150 |
| 2 | 0 | 200 |
| 3 | 100 | 300 |

Was genau erwartest du dann für eine Anzeige?

Etwa das :

teilnehmer : 3
gesamt : 953 - 231 = 722 ?
min : [Uid3 = 200], [Uid2 320], [Uid1: 202] also 200 ?
max : dementsprechend dann 320 ?
avg : (200+320+202) / 3 = 241 ?

Oder etwas ganz anderes?

Bei obigem Beispiel wirst du das wahrscheinlich mit einer einzigen Abfrage nicht lösen können. Zumindest würde mir nichts passendes dazu einfallen. Oder liege ich falsch ?

SebbyPHM
03.12.2008, 20:43
SELECT
COUNT(*) AS teilnehmer,
SUM(bis-von) AS gesamt,
MIN(bis-von) AS min,
MAX(bis-von) AS max,
AVG(bis-von) AS avg
FROM
verlosung
GROUP BY
uid
LIMIT 1

Warum machst du ein GROUP BY uid, und ein COUNT(*) AS teilnehmer?

-->


SELECT
COUNT(uid) AS teilnehmer,
SUM(bis-von) AS gesamt,
MIN(bis-von) AS min,
MAX(bis-von) AS max,
AVG(bis-von) AS avg
FROM
verlosung
LIMIT 1

??

Sebmaster
03.12.2008, 20:58
SELECT
COUNT(uid) AS teilnehmer,
SUM(bis-von) AS gesamt,
MIN(bis-von) AS min,
MAX(bis-von) AS max,
AVG(bis-von) AS avg
FROM
verlosung
LIMIT 1??

Da kommt als Teilenehmer (bei Grmlins Beispiel) aber 2 raus, obwohls 2x die selbe uid ist und Grmelin dann das nur als einen zählen will:knueppel:

VMS1
03.12.2008, 21:06
Jetzt verstehe ich erst das Prinzip von der Tabelle glaub ich. Das sollen jeweils die Positionen sein, die der User jeweils hält. Naja, ändert ja nicht viel, außer das ich im obigen Beispiel etwas abstrakte Werte angegeben habe.

Nehmen wir mal das Beispiel :

1 | 0 | 100
1 | 101| 203
2 | 300 | 330
2 | 340 | 410
3 | 500 | 560

Also eine Abfrage für :

1.) Gesamtanzahl der Teilnehmer
2.) Gesamtanzahl von Positionen im System
3.) Anzahl der Positionen, die der User mit den meisten Positionen insgesamt hält
4.) Anzahl der Positionen, die der User mit den wenigsten Positionen insgesamt hält
5.) Die Anzahl der Positionen, die jeder User durchschnittlich hält

Mittlerweile ist mir da auch etwas zu eingefallen :


SELECT COUNT( DISTINCT uid ) AS teilnehmer, SUM( bis - von ) AS gesamt, MAX( (

SELECT SUM( bis - von )
FROM verlosung
GROUP BY uid
ORDER BY bis - von DESC
LIMIT 1 )
) AS max, MIN( (

SELECT SUM( bis - von )
FROM verlosung
GROUP BY uid
ORDER BY bis - von ASC
LIMIT 1 )
) AS min
FROM verlosung

Das AVG schenken wir uns in der Abfrage, weil das ja eigentlich (gesamt/teilnehmer) sein sollte.

Richtig?^^

Gremlin
03.12.2008, 21:27
@VMS1
Genau so ist es :thumb:. Super, danke dir!