Komplizierte MySQL-Abfrage!?
Julia
- datenbank
Hallo MySQL-Profis,
ich stehe hier vor einem Problem. Ich soll für eine Spendenorganisation eine Art Highscore-Liste für Spenden erstellen.
Die einzige Tabelle aus der die Daten kommen sieht folgendermaßen aus:
aktion | name | spende | datum |
---------------------------------------
flut | anton | 10 |2004-12-29
flut | berta | 15 |2004-12-30
flut | cäsar | 5 |2005-01-15
erdbeben| anton | 5 |2005-01-20
erdbeben| berta | 25 |2005-01-21
erdbeben| cäsar | 5 |2005-01-22
.
.
.
Die Ausgabe soll später so aussehen:
name | flut | erdbeben | gesamt
-------------------------------
berta| 15 | 25 | 40
anton| 10 | 5 | 15
cäsar| 5 | 5 | 10
.
.
.
Die Sortierung erfolgt also nach der Gesamtspendensumme des Spenders.
Lässt sich das durch eine MySQL-Abfrage abbilden? Wenn ja, hat jemand ein paar Ansätze die mir weiterhelfen könnten. Ich weiß ehrlich gesagt nicht wie ich das anfangen soll.
MySQL Version 4.0.18/PHP 4.2.2
Ich bin für jede Hilfe Dankbar!
Schöne Grüße
Julia
Halihallo Julia
name | flut | erdbeben | gesamt
berta| 15 | 25 | 40
anton| 10 | 5 | 15
cäsar| 5 | 5 | 10
Die Sortierung erfolgt also nach der Gesamtspendensumme des Spenders.Lässt sich das durch eine MySQL-Abfrage abbilden? Wenn ja, hat jemand ein paar Ansätze die mir weiterhelfen könnten. Ich weiß ehrlich gesagt nicht wie ich das anfangen soll.
Generell und allgemein gesagt Nein. MySQL bzw. SQL unterstützt kein
Abbilden von Attributwerten in Attributnamen (flug und erdbeben sind
ja Attributwerte und sollen in der Ausgabe *plötzlich* zu
Attributnamen verwandelt werden, das ist böse Magie!).
Speziell aber ja. Speziell genau dann, wenn du eine fixe Anzahl an
Katastrophen hast (im Beispiel 2) bzw. eine Technik wie PHP was dir
ja zur Verfügung steht, mit Hilfe dieser du die Anfrage dynamisch
zusammenstellen kannst.
Dann geht's sinngemäss über korrelierte Subqueries so:
SELECT
a.name,
(
SELECT SUM(spende) FROM table WHERE name=a.name
WHERE aktion='flut'
) AS 'flut',
(
SELECT SUM(spende) FROM table WHERE name=a.name
WHERE aktion='erdbeben'
) AS 'erdbeben',
(
SELECT SUM(spende) FROM table WHERE name=a.name
) AS 'gesamt'
FROM table AS a
GROUP BY a.name
ORDER BY gesamt
Nun, jeder Datenbankexperte würde dich für dieses Konstrukt zwar
umbringen und die meisten Datenbanken quittieren dir den Dienst mit
einer Fehlermeldung, aber ich könnte mir doch vorstellen, dass MySQL
da mitmacht.
Oftmals werden Subqueries in der SELECT-Klausel ganz verweigert.
Andere Datenbanken (z.B. DB2) lassen einwertige und einattributige
Subqueries in SELECT zu.
Zudem sind diese korrelierten Subqueries, wenn es eine schnellere
Lösung gibt, zu unterlassen (was für eine Erkenntnis :-)).
Eine andere, aber ebenso stupide Lösung wäre über drei Joins zu
gehen. Ggf. mit der Prämisse, dass jeder mindestens einmal für jede
Katastrophe spendet, dann gehts sogar ohne grössere Tricks
(unbestätigt aber etwas bedacht in den Raum geworfen).
Nun, zusammenfassend: Über eine SQL-Anfrage würde ich dies kaum
machen, besonders nicht weil du PHP als Vorhanden zeichnest. Überlege
dir, wie du mit PHP und zwei SQL-Anfragen an dein Ziel kommst.
Viele Grüsse
Philipp
Hallo
nur als Ergänzung zu Philipps Ausführungen:
name | flut | erdbeben | gesamt
berta| 15 | 25 | 40
anton| 10 | 5 | 15
cäsar| 5 | 5 | 10
Generell und allgemein gesagt Nein. MySQL bzw. SQL unterstützt kein
Abbilden von Attributwerten in Attributnamen (flug und erdbeben sind
ja Attributwerte und sollen in der Ausgabe *plötzlich* zu
Attributnamen verwandelt werden, das ist böse Magie!).
Jet-SQL, d.h. der SQL-Dialekt, den die Jet-Database-Engine, die v.a. hinter Microsoft Access steckt, unterstützt diese Anforderung. Das nennt sich in Access Kreuztabellenabfrage.
Syntax:
TRANSFORM Aggregatfunktion
SELECT-Anweisung
PIVOT PivotFeld [IN (Wert1[, Wert2[, ...]])]
Freundliche Grüße
Vinzenz
yo,
ja Attributwerte und sollen in der Ausgabe *plötzlich* zu
Attributnamen verwandelt werden, das ist böse Magie!).
oder PL/SQL....
»» Zudem sind diese korrelierten Subqueries, wenn es eine schnellere
Lösung gibt, zu unterlassen (was für eine Erkenntnis :-)).
eventuell sollte es auch über GROUP BY aktion, name gehen und zusätzlich über Control Flow Functions wie IF, die den inhalt von aktion überprüft und entsprechend verzweigt. damit sollten sich die unterabfragen vermeiden lassen (ohne prügunf nur eine fixe idee). aber auch hierzu muss man die namen der einzelnen katastrophen kennen und somit die anzahl.
Ilja
Halihallo Ilja
Zudem sind diese korrelierten Subqueries, wenn es eine schnellere
Lösung gibt, zu unterlassen (was für eine Erkenntnis :-)).eventuell sollte es auch über GROUP BY aktion, name gehen und zusätzlich über Control Flow Functions wie IF, die den inhalt von aktion überprüft und entsprechend verzweigt. damit sollten sich die unterabfragen vermeiden lassen (ohne prügunf nur eine fixe idee). aber auch hierzu muss man die namen der einzelnen katastrophen kennen und somit die anzahl.
Ich glaube, dass käme auf meine Drei-Join-Aufgabe heraus, denn
andernfalls bringt dir IF wenig, da es nach dem GROUP BY
Interpretiert wird. Die Daten befänden sich bereits im aggregierten
Zustand und wären für IF unverwertbar.
Viele Grüsse
Philipp
yo,
Ich glaube, dass käme auf meine Drei-Join-Aufgabe heraus, denn
andernfalls bringt dir IF wenig, da es nach dem GROUP BY
Interpretiert wird. Die Daten befänden sich bereits im aggregierten
sicherlich war bei mir eine spalte im group by zuviel, aber es sollte meiner meinung nach ohne joins und subquerys so gehen.
SELECT name, SUM(IF(aktion="flut", spende, 0)) As Flut, SUM(IF(aktion="erdbeben", spende, 0)) AS Erdbeben, SUM(spende) AS Gesamt
FROM gruppe
GROUP BY name
ORDER BY 4 DESC
Ilja
Halihallo Ilja
SELECT name, SUM(IF(aktion="flut", spende, 0)) As Flut, SUM(IF(aktion="erdbeben", spende, 0)) AS Erdbeben, SUM(spende) AS Gesamt
FROM gruppe
GROUP BY name
ORDER BY 4 DESC
Du hast recht. Ich dachte, dass hier IF nicht geht, da es sich auf
ein aggregiertes Attribut bezieht. Es funktioniert jedoch, wie ich
eben versucht habe. Ist ja eigentlich auch logisch, wie so vieles im
Nachhinein :-)
Schöne Ostern und Dank der Korrektur
Philipp
yo,
Schöne Ostern und Dank der Korrektur
nun, jedesmal wenn wir vorher miteinander diskutiert haben, war es sehr lehrreich für mich. ich denke mal, sehr bald werde ich wieder die oster-hasen-ohren aufsperren...
prost und frohe ostern
Ilja
Halihallo Ilja
Schöne Ostern und Dank der Korrektur
nun, jedesmal wenn wir vorher miteinander diskutiert haben, war es sehr lehrreich für mich.
Vielen Dank, es war mir stets eine herausfordernde Freude :-)
prost und frohe ostern
YYYYYYYYYYYYYY und gleichfalls.
Viele Grüsse
Philipp