schneerunzel
Goto Top

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:
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:
unbenannt

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

Content-ID: 348256

Url: https://administrator.de/contentid/348256

Ausgedruckt am: 22.11.2024 um 13:11 Uhr

em-pie
em-pie 05.09.2017 aktualisiert um 21:23:46 Uhr
Goto Top
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

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
Biber
Biber 05.09.2017 um 22:53:04 Uhr
Goto Top
Moin schneerunzel,

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?
atze187
Lösung atze187 06.09.2017 um 08:42:31 Uhr
Goto Top
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