Mittelwert gleicher Datensätze in MySQL-DB
Philip
- php
Hi,
ich hab in einer Datenbank Datensätze mit USB-Sticks. Ein USB-Stick kann mehrmals vorkommen, zu jedem Stick gibt es verschiedene Werte wie Preise und Speichergröße.
Kommt ein Stick mehrfach vor, soll er aber nur einmal ausgegeben werden, als Preis und Kapazität soll der Mittelwert berechnet werden.
Kann ich das direkt so aus der DB auslesen oder muss ich das mühsam einzeln auslesen und irgendwie mit Arrays zwischenspeichern?
Hello,
das sollte kein Problem sein. Verwende GROUP BY mit der Funktion AVG. Bitte komme dabei NICHT auf die Idee die MySQL-Macke auszunutzen dir nicht-gruppierte, nicht-aggregierte Werte zu selektieren - Bsp.:
Gut:
SELECT a, b, SUM(c), AVG(d)
FROM x
GROUP BY a, b
Schlecht
SELECT a, b, SUM(c)
FROM x
GROUP BY a
--> Wert für b ist pseudo-definiert.
MfG
Rouven
Hi,
die MySQL-Seite habe ich gerade gefunden, aber komme mit dem Syntax nicht zurecht.
In meinem Fall müsste das doch so aussehen:
SELECT usbstick, AVG(preis) FROM usb GROUP BY usbstick;
Allerdings brauche ich ja auch noch AVG(speicher)
Keine Ahnung, wie ich das zusammenfasse und dann alle Daten ausgeben kann. Mit dieser Abfrage habe ich ja dann nur den durchschnittlichen Preis bzw. Speicher!?
Hello,
hängt einfach eine weitere Spalte an...
SELECT usbstick, AVG(preis) AS preis, AVG(speicher) AS speicher FROM usb GROUP BY usbstick;
MfG
Rouven
Okay danke, aber wo sind diese Daten denn dann?
Denn wenn ich jetzt einfach meine Abfrage für alle Daten starte
$abfrage = "SELECT * FROM usb ORDER BY usbstick ASC";
$ergebnis = mysql_query($abfrage);
while($row = mysql_fetch_object($ergebnis))
{
echo $row-> usbstick.", ";
echo $row->preis", ";
echo $row->speicher".\n";
}
ist das doch wieder über den Haufen?!
Hello,
$abfrage = "SELECT * FROM usb ORDER BY usbstick ASC";
bitte benutze SELECT * nur zu Testzwecken und gib in allen anderen Fällen genau die Spalten an, die du benötigst.
echo $row-> usbstick.", ";
echo $row->preis", ";
echo $row->speicher".\n";
wenn du davon ausgehst, dass du Spalten unter genau diesen Namen bekommst, dann benenne die Aggregationen auch so:
SELECT usbstick, AVG(preis) AS preis, AVG(speicher) AS speicher
FROM usb
GROUP BY usbstick
ORDER BY usbstick
MfG
Rouven
D.h. dieses
$abfrage = SELECT usbstick, AVG(preis) AS preis, AVG(speicher) AS speicher FROM usb GROUP BY usbstick ORDER BY usbstick ASC
ersetzt mein ganzes
$abfrage = "SELECT * FROM usb ORDER BY usbstick ASC";
und weitere Felder kann ich einfach mit , dazwischenklemmen?
Hello,
und weitere Felder kann ich einfach mit , dazwischenklemmen?
ahhhh - VORSICHT! NEIN! Genau das sollst du NUR DANN tun, wenn du die Felder entweder in der GROUP BY-Klausel hast, oder sie von einer Aggregatsfunktion begleitet werden. Du solltest nie nie nie nie nie folgendes machen:
SELECT usbstick, beschreibung, AVG(preis), AVG(groesse)
FROM usb
GROUP BY usbstick
NIcht-MySQL-Datenbanken hauen dir das Statement (IMHO korrekterweise) um die Ohren. MySQL hat eine (IMHO gefährliche) Sonderlocke, die das trotzdem durchlässt, vgl. verdeckte Felder
MfG
Rouven
Du solltest nie nie nie nie nie folgendes machen:
SELECT usbstick, beschreibung, AVG(preis), AVG(groesse)
FROM usb
GROUP BY usbstick
Das ist doch das, was du geschrieben hattest:
SELECT usbstick, AVG(preis) AS preis, AVG(speicher) AS speicher FROM ...
Was versteh ich gerade nicht bzw. was mache ich dann wenn ich noch weitere Felder brauche, diese aber nicht "dazwischenklemmen" soll? :D
So,
es klappt es wunderbärchen :D
Vielen Dank für die schnelle Hilfe.