FB18 - Das Forum für Informatik

fb18.de / Off-Topic / Hard- und Softwarefragen

Daten aggregieren mit SQL?

Daten aggregieren mit SQL? 2009-08-27 23:53
Muelli
Ahoi,

sorry fuer das komische Subject, aber mir fiel nichts treffenderes ein.

Ich hab ein Problem, was ich gerade nicht mit SQL erschlagen kann, aber will ;-)

Ich habe da so eine Mitgliederdatenbank mit einem Datumsfeld "renewed_on".
Eine Mitgliedschaft ist "aktiv" wenn sie vor spaetestens einem Monat renewed worden ist.
Nun will ich also wissen, wer aktiv ist.
SELECT firstname, lastname, renewed_on FROM members WHERE renewed_on <= DATE_SUB(CURDATE(), INTERVAL 1 MONTH);
Kein Problem.

Aber nun moechte ich die Anzahl der Mitglieder ueber die Zeit haben.
Also sowas wie
SELECT DATE_FORMAT(renewed_on, '%Y-%m') AS renewed, COUNT(*) FROM members GROUP BY renewed;
+———+———-+
| renewed | COUNT(*) |
+———+———-+
| 2008-10 |       16 |
| 2008-11 |        8 |
| 2008-12 |        2 |
+———+———-+
Aber das macht natuerlich nicht das, was ich moechte, weil es nicht die Mitglieder des letzten Monats aggregiert, sondern nur die "neuen" Mitglieder aufzeigt.

Im Prizip will ich ein Query, was die folgende Ausgabe (auf Basis der o.g. Daten) produziert
+———+———-+
| all_members | COUNT(*) |
+———+———-+
| 2008-10 |       16 |
| 2008-11 |        24 |
| 2008-12 |        10 |
+———+———-+

Mein Ansatz waere jetzt, mit einem Programm ueber die Monate zu iterieren und die Daten entsprechend zu aggregieren,a ber ich hoffe auf ein SQL Loesung, damit ich weniger programmieren muss :P

RE: Daten aggregieren mit SQL? 2009-08-28 01:54
Anonymer User
Datumsarithmetik ist eine Pest bei MySQL…

SELECT Abrechnungsmonat
, COUNT(*) as Abrechnungsmenge
FROM members
, (
SELECT DATE_FORMAT(renewed_on, '%Y-%m') as Abrechnungsmonat
, STR_TO_DATE(DATE_SUB(DATE_FORMAT(renewed_on, '%Y-%m-01'), INTERVAL 1 MONTH), '%Y-%m-%d') as Zeitraum_Anfang
, STR_TO_DATE(DATE_ADD(DATE_FORMAT(renewed_on, '%Y-%m-01'), INTERVAL 1 MONTH), '%Y-%m-%d')  as Zeitraum_Ende
FROM members
GROUP BY Abrechnungsmonat;
) e
WHERE members.renewed_on >= Zeitraum_Anfang
AND members.renewed_on < Zeitraum_Ende
GROUP BY Abrechnungsmonat
;

Alles ungetestet und ohne Gewähr.

RE: Daten aggregieren mit SQL? 2009-08-28 02:09
Muelli
Wow, Amazing!
Ich bin tief beeindruckt. Also das Query musste bisschen feingeschliffen werden, aber im Prinzip tut es genau das, was ich will.
SELECT Abrechnungsmonat, COUNT(*) as Abrechnungsmenge FROM foundationmembers, ( SELECT DATE_FORMAT(last_renewed_on, '%Y-%m') as Abrechnungsmonat, STR_TO_DATE(DATE_SUB(DATE_FORMAT(last_renewed_on, '%Y-%m-01'), INTERVAL 2 YEAR), '%Y-%m-%d') as Zeitraum_Anfang, STR_TO_DATE(DATE_ADD(DATE_FORMAT(last_renewed_on, '%Y-%m-01'), INTERVAL 2 YEAR), '%Y-%m-%d')  as Zeitraum_Ende FROM foundationmembers GROUP BY Abrechnungsmonat ) foo WHERE foundationmembers.last_renewed_on >= Zeitraum_Anfang AND foundationmembers.last_renewed_on < Zeitraum_Ende GROUP BY Abrechnungsmonat; (Eh, kacke. die code Umgebung macht Whitespaces kaputt. Wie dumm ist das denn…)

Verstehen tu ich das nicht so recht. Also insbesondere dass man die Daten aus dem Subquery wieder referenzieren kann und so. Ich bekomme meinen Kopf wohl nicht so gut um SQL gewickelt. Gottseidank sind wir das bald los :P

Ich schulde dir ein Bier! Am besten kommst du das naechste Mal zu den Nomaden! :-)