MySQL: Auswertung des Alters
Hallo zusammen,
für einen Report möchte ich gerne aus unserer Mitglieder Datenbank eine Altersstatistik rauszieren:
Alter W M
1 1 0
2 2 4
3 0 1
etc.
Die Tabelle ist so aufgebaut, das ich eine Spalte für das Geburtsdatum und eine für das Geschlecht habe.
Ich hatte mir folgenden SQL Befehl dafür überlegt:
Leider kommt da folgendes Ergebnis bei raus:
was mache ich falsch.
Im Moment vermute ich, das der Counter auch bei allen Subquerys mit hoch zählt....
Vielen Dank für Eure Hilfe
für einen Report möchte ich gerne aus unserer Mitglieder Datenbank eine Altersstatistik rauszieren:
Alter W M
1 1 0
2 2 4
3 0 1
etc.
Die Tabelle ist so aufgebaut, das ich eine Spalte für das Geburtsdatum und eine für das Geschlecht habe.
Ich hatte mir folgenden SQL Befehl dafür überlegt:
select @rownum := @rownum + 1 as row_number,
(select count(*) from mitglied where mitglied.geschlecht = "w" and FLOOR(datediff(current_date(), mitglied.geburtsdatum)/365) = row_number) as w,
(select count(*) from mitglied where mitglied.geschlecht = "m" and FLOOR(datediff(current_date(), mitglied.geburtsdatum)/365) = row_number) as m
from mitglied
cross join (select @rownum := 0) r
Leider kommt da folgendes Ergebnis bei raus:
was mache ich falsch.
Im Moment vermute ich, das der Counter auch bei allen Subquerys mit hoch zählt....
Vielen Dank für Eure Hilfe
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 348256
Url: https://administrator.de/contentid/348256
Ausgedruckt am: 22.11.2024 um 13:11 Uhr
3 Kommentare
Neuester Kommentar
Moin,
also wie ICH es machen würde:
als erstes (wie du es ja auch schon gemacht hast) für jedes Geschlecht ein eigenes Query
Dann beides mit UNION ALL kombinieren:
Die Spalten mit den Inhalten 0 bzw. 1 sind dafür gut, dass du für die Mädels und die Jungs jeweils eine Art "Counter" hast
Anschließend in Klammern setzen und darüber ein Group By laufen lassen. Fertig (ungetestet)
Teste das einfach mal, ganz sicher bin ich mir nicht, sollte aber zum Ziel führen
Gruß
em-pie
€dit: Typo
also wie ICH es machen würde:
als erstes (wie du es ja auch schon gemacht hast) für jedes Geschlecht ein eigenes Query
SELECT DATE_FORMAT(DATEDIFF(current_date(), mitglied.geburtsdatum), %Y) as "YEARS", 1 "w" FROM mitglied WHERE mitglied.geschlecht='w'
SELECT DATE_FORMAT(DATEDIFF(current_date(), mitglied.geburtsdatum), %Y) as "YEARS", 1 "m" FROM mitglied WHERE mitglied.geschlecht='m'
Dann beides mit UNION ALL kombinieren:
SELECT DATE_FORMAT(DATEDIFF(current_date(), mitglied.geburtsdatum), %Y) as "YEARS", 1 as "w", 0 as "w" FROM mitglied WHERE mitglied.geschlecht='w'
UNION ALL
SELECT DATE_FORMAT(DATEDIFF(current_date(), mitglied.geburtsdatum), %Y) as "YEARS", 0 as "w", 1 as "m" FROM mitglied WHERE mitglied.geschlecht='m'
Die Spalten mit den Inhalten 0 bzw. 1 sind dafür gut, dass du für die Mädels und die Jungs jeweils eine Art "Counter" hast
Anschließend in Klammern setzen und darüber ein Group By laufen lassen. Fertig (ungetestet)
SELECT
YEARS
, SUM(w) as w
, SUM(m) as m
FROM (
SELECT DATE_FORMAT(DATEDIFF(current_date(), mitglied.geburtsdatum), %Y) as "YEARS", 1 as "w", 0 as "m" FROM mitglied WHERE mitglied.geschlecht='w'
UNION ALL
SELECT DATE_FORMAT(DATEDIFF(current_date(), mitglied.geburtsdatum), %Y) as "YEARS", 0 as "w", 1 as "m" FROM mitglied WHERE mitglied.geschlecht='m'
)
GROUP by YEARS
ORDER by YEARS
Teste das einfach mal, ganz sicher bin ich mir nicht, sollte aber zum Ziel führen
Gruß
em-pie
€dit: Typo
Moin schneerunzel,
ich finde, ihr solltet es nicht unnöig kompliziert machen.
Mein ungetesteter Vorschlag wäre:
Bei der Altersberechnung prüfe ich, ob das Mitglied (m/w) dieses Jahr schon Geburtstag hatte oder noch nicht. Damit wird die Jahresdifferenz (volle Jahre) ggf um 1 berichtigt.
Mit deiner Floor()-Mimik geht es natürlich auch.
.
Bei mir werden natürlich nur Alters-Werte angezeigt, die es auch gibt (also nicht Alter 0, 1....99 lückenlos).
Grüße
Biber
P.S. Wer hat denn das Anmeldebildschirm-Layout geändert?
Sieht ja pottenhässlich aus. Neuer Praktikant beim WebMassa?
ich finde, ihr solltet es nicht unnöig kompliziert machen.
Mein ungetesteter Vorschlag wäre:
SELECT alterInJahren
, sum(maedels) as 'w'
, sum(jungs) as 'm'
FROM (
SELECT (year(current_date) - year(geburtstagsdatum))
- (date_format(current_date),'%d%m') < date_format(geburtstagsdatum,'%d%m') )
as alterInJahren
, Case when geschlecht='w' then 1 else 0 End as maedels
, Case when geschlecht='m' then 1 else 0 End as Jungs
FROM Mitglieder
) as details
GROUP BY alterInJahren
ORDER by 1;
Bei der Altersberechnung prüfe ich, ob das Mitglied (m/w) dieses Jahr schon Geburtstag hatte oder noch nicht. Damit wird die Jahresdifferenz (volle Jahre) ggf um 1 berichtigt.
Mit deiner Floor()-Mimik geht es natürlich auch.
.
Bei mir werden natürlich nur Alters-Werte angezeigt, die es auch gibt (also nicht Alter 0, 1....99 lückenlos).
Grüße
Biber
P.S. Wer hat denn das Anmeldebildschirm-Layout geändert?
Sieht ja pottenhässlich aus. Neuer Praktikant beim WebMassa?
Erstaunlicherweise ist das der Weg. Erstaunlich vor allem deshalb wenn man weiß wie stark sich die SQL-Dialekte aus dem Hause Oracle bei den Rückgabewerten dieser doch recht unspektakulären, aber häufig genutzten Funktion von anderen unterscheiden:
MySQL: Tage
PL-SQL: Tage, Sekunden
T-SQL: alles von Jahren bis hinunter zu Nanosekunden
Firebird: Jahre bis Millisekunden
PostgreSQL: Jahre bis Sekunden
MySQL: Tage
PL-SQL: Tage, Sekunden
T-SQL: alles von Jahren bis hinunter zu Nanosekunden
Firebird: Jahre bis Millisekunden
PostgreSQL: Jahre bis Sekunden