Ankündigung

Einklappen
Keine Ankündigung bisher.

Nächste Geburtstage aus Datenbank auslesen

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Nächste Geburtstage aus Datenbank auslesen

    Hallo,

    ich bin neu hier im Forum und habe auch schon meine erste Frage. Und zwar besitze ich eine Datenbank mit den Spalten 'Name' und 'Geburtstdatum' im Formt '0000-00-00'.
    Nun möchte ich gerne dass mir die Namen der nächsten 5 Geburtstage ausgegeben werden.

    Habe dazu schon einige Lösungsansätze im Internet gefunden, doch leider hat keiner davon funktioniert. Ich denke dass so etwas leicht umsetzbar ist, doch dazu reichen meine SQL-Kenntnisse nicht aus.

    Vielen Dank schon mal für eure Hilfe!

    LG, Tobias


  • #2
    So vielleicht...?

    Code:
    CREATE TABLE geburtstag (
      id INT NOT NULL,
      name VARCHAR(50) NOT NULL,
      gebtag DATE NOT NULL
    );
    
    INSERT INTO geburtstag VALUES
    ( 1, 'Fritz-1', '2010-01-10'),
    ( 2, 'Fritz-2', '2010-02-10'),
    ( 3, 'Fritz-3', '2010-03-10'),
    ( 4, 'Fritz-4', '2010-04-10'),
    ( 5, 'Fritz-5', '2010-05-10'),
    ( 6, 'Fritz-6', '2010-06-10'),
    ( 7, 'Fritz-7', '2010-07-10'),
    ( 8, 'Fritz-8', '2010-08-10'),
    ( 9, 'Fritz-9', '2010-09-10'),
    (10, 'Fritz-10', '2010-10-10'),
    (11, 'Fritz-11', '2010-11-10'),
    (12, 'Fritz-12', '2010-12-10');
    
    SELECT name, gebtag
      FROM geburtstag
     WHERE gebtag >= CURRENT_DATE
     ORDER BY gebtag
    LIMIT 5;
    
    +----------+------------+
    | name     | gebtag     |
    +----------+------------+
    | Fritz-6  | 2010-06-10 |
    | Fritz-7  | 2010-07-10 |
    | Fritz-8  | 2010-08-10 |
    | Fritz-9  | 2010-09-10 |
    | Fritz-10 | 2010-10-10 |
    +----------+------------+
    5 rows in set (0.05 sec)
    
    mysql>
    Grüße
    Thomas

    Kommentar


    • #3
      @thomas_w: Meinst Du der findet auch Daten von bereits geborenen Menschen? Da sind wird wieder beim Testen von Applikationen angelangt.
      Mir ist gerade bei meiner gedachten Lösung aufgefallen, dass damit Schaltjahre zum Problem werden könnten.

      Kommentar


      • #4
        Zitat von Sascha Ahlers Beitrag anzeigen
        @thomas_w: Meinst Du der findet auch Daten von bereits geborenen Menschen? Da sind wird wieder beim Testen von Applikationen angelangt.
        Stimmt, da bin ich gleich mal voll reingetreten. Aber okay, ich baue den SQL um und melde mich gleich wieder.

        Danke für den Hinweis!!

        Grüße
        Thomas

        Kommentar


        • #5
          So wird das Geburtsdatum wohl nicht vorliegen. Du musst das Jahr des Geburtstages ersetzen, und zwar wenn der diesjährige Geburtstag schon rum ist, dann mit dem nächsten Jahr, andernfalls mit dem aktuellen. Danach sortieren und limitieren.

          Code:
          SELECT
            IF (
              DAYOFYEAR(CURDATE()) < DAYOFYEAR(gebtag)), -- Geburtstag vorbei?
              DATE_FORMAT(gebtag, CONCAT(YEAR(CURDATE()), '-%m-%d')), -- Nein: dann Geburtsjahr mit dem aktuellen ersetzen
              DATE_FORMAT(gebtag, CONCAT(YEAR(CURDATE()) + 1, '-%m-%d')) -- Ja: dann Geburtsjahr mit dem nächsten Jahr ersetzen
            ) AS gebtag_aktuell -- und Alias erzeugen
          FROM
          ORDER BY
            IF (
              DAYOFYEAR(CURDATE()) < DAYOFYEAR(gebtag)), -- gleiche Prozedur (muss soweit ich weiß, andernfalls probier mal nach ORDER BY gebtag_aktuell DESC zu sortieren)
              DATE_FORMAT(gebtag, CONCAT(YEAR(CURDATE()), '-%m-%d')),
              DATE_FORMAT(gebtag, CONCAT(YEAR(CURDATE()) + 1, '-%m-%d'))
            ) DESC
          (ungetestet)

          Zum Thema Schaltjahre musst du dann eben Strings bauen, will heißen: auf DAYOFYEAR() verzichten. Du musst das eigentlich nur mal auf dem Papier aufmalen:

          29. Februar 200x vs 1. März 200x. PHPs Datumsfunktionen können dir beispielsweise den 29. Februar, wenn es ihn nicht gibt, automatisch auf den 1. März umdrücken. Denke die MySQL hat ähnliche Fähigkeiten.
          "Mein Name ist Lohse, ich kaufe hier ein."

          Kommentar


          • #6
            So jetzt aber nochmal.

            noch ein paar Testdaten dazu ( 2009 und 2008 )
            Code:
            INSERT INTO geburtstag VALUES
            (13, 'Fritz-13', '2009-01-10'),
            (14, 'Fritz-14', '2009-02-10'),
            (15, 'Fritz-15', '2009-03-10'),
            (16, 'Fritz-16', '2009-04-10'),
            (17, 'Fritz-17', '2009-05-10'),
            (18, 'Fritz-18', '2009-06-10'),
            (19, 'Fritz-19', '2009-07-10'),
            (20, 'Fritz-20', '2009-08-10'),
            (21, 'Fritz-21', '2009-09-10'),
            (22, 'Fritz-22', '2009-10-10'),
            (23, 'Fritz-23', '2009-11-10'),
            (24, 'Fritz-24', '2009-12-10');
            
            INSERT INTO geburtstag VALUES
            (25, 'Fritz-25', '2008-01-10'),
            (26, 'Fritz-26', '2008-05-10'),
            (27, 'Fritz-27', '2008-10-10');
            Jetzt mal alles nach GEBTAG sortiert ausgeben (auch wenn er in der Zukunft liegt.)

            Code:
            mysql> SELECT * FROM geburtstag
                -> ORDER BY gebtag
                -> ;
            +----+----------+------------+
            | id | name     | gebtag     |
            +----+----------+------------+
            | 25 | Fritz-25 | 2008-01-10 |
            | 26 | Fritz-26 | 2008-05-10 |
            | 27 | Fritz-27 | 2008-10-10 |
            | 13 | Fritz-13 | 2009-01-10 |
            | 14 | Fritz-14 | 2009-02-10 |
            | 15 | Fritz-15 | 2009-03-10 |
            | 16 | Fritz-16 | 2009-04-10 |
            | 17 | Fritz-17 | 2009-05-10 |
            | 18 | Fritz-18 | 2009-06-10 |
            | 19 | Fritz-19 | 2009-07-10 |
            | 20 | Fritz-20 | 2009-08-10 |
            | 21 | Fritz-21 | 2009-09-10 |
            | 22 | Fritz-22 | 2009-10-10 |
            | 23 | Fritz-23 | 2009-11-10 |
            | 24 | Fritz-24 | 2009-12-10 |
            |  1 | Fritz-1  | 2010-01-10 |
            |  2 | Fritz-2  | 2010-02-10 |
            |  3 | Fritz-3  | 2010-03-10 |
            |  4 | Fritz-4  | 2010-04-10 |
            |  5 | Fritz-5  | 2010-05-10 |
            |  6 | Fritz-6  | 2010-06-10 |
            |  7 | Fritz-7  | 2010-07-10 |
            |  8 | Fritz-8  | 2010-08-10 |
            |  9 | Fritz-9  | 2010-09-10 |
            | 10 | Fritz-10 | 2010-10-10 |
            | 11 | Fritz-11 | 2010-11-10 |
            | 12 | Fritz-12 | 2010-12-10 |
            +----+----------+------------+
            27 rows in set (0.00 sec)
            
            mysql>
            Dann mal eine Auswertung...

            Code:
            SELECT name, gebtag
              FROM geburtstag
             WHERE DATE_FORMAT(gebtag, '%m.%d') >= DATE_FORMAT(CURRENT_DATE(),'%m.%d')
               AND DATE_FORMAT(gebtag,'%Y') < DATE_FORMAT(CURRENT_DATE(),'%Y')
             ORDER BY DATE_FORMAT(gebtag,'%m.%d')
            LIMIT 5;
            
            +----------+------------+
            | name     | gebtag     |
            +----------+------------+
            | Fritz-18 | 2009-06-10 |
            | Fritz-19 | 2009-07-10 |
            | Fritz-20 | 2009-08-10 |
            | Fritz-21 | 2009-09-10 |
            | Fritz-22 | 2009-10-10 |
            +----------+------------+
            5 rows in set (0.01 sec)
            Was habe ich nun noch falsch gemacht?

            Okay, den 29.02. muss ich noch testen...

            Grüße
            Thomas

            Kommentar


            • #7
              Damit wirst du zum Jahreswechsel Probleme haben: Heute 31.12., morgen hat aber Geburtstag Neujahrskind Hans-Peter, der wäre in deiner WHERE-Bedingung schon rausgeflogen. Drum musst du das Geburtsjahr ersetzen (Bedingung ob schon heuer gewesen) und danach kannst du erst sortieren.
              "Mein Name ist Lohse, ich kaufe hier ein."

              Kommentar


              • #8
                Stimmt, da habe ich mich jetzt total verzettelt, sorry.
                Muss noch mal in Ruhe drüber nachdenken. Dass wird heute bei mir nichts mehr.

                EDIT
                Bin noch dran, kann aber noch dauert...

                Grüße
                Thomas

                Kommentar


                • #9
                  Nun eine neue Idee zur Geburtstagsliste. Die Logik habe ich in ein Stored Procedure
                  gelegt, damit die SQL übersichtlicher sind. Das Ganze ist eine spezielle MySLQ Lösung.


                  -- Die Tabelle plus Testdaten
                  Code:
                  CREATE TABLE geburtstag (
                    id INT NOT NULL,
                    name VARCHAR(50) NOT NULL,
                    gebtag DATE NOT NULL
                  );
                  
                  INSERT INTO geburtstag VALUES
                  (1, 'Fritz-1', '2004-02-29'),
                  (2, 'Fritz-2', '2008-02-29'),
                  (3, 'Fritz-3', '2005-01-01'),
                  (4, 'Fritz-4', '2004-12-31'),
                  (5, 'Fritz-5', '2007-02-01'),
                  (6, 'Fritz-6', '2007-03-01'),
                  (7, 'Fritz-7', '2007-04-01'),
                  (8, 'Fritz-8', '2007-05-01'),
                  (9, 'Fritz-9', '2007-06-01'),
                  (10, 'Fritz-10', '2007-07-01'),
                  (11, 'Fritz-11', '2007-08-01'),
                  (12, 'Fritz-12', '2007-09-01');
                  -- Testdaten sortiert nach MM.DD
                  Code:
                  SELECT * FROM geburtstag
                  ORDER BY DATE_FORMAT(gebtag,'%m.%d');
                  
                  
                  +----+----------+------------+
                  | id | name     | gebtag     |
                  +----+----------+------------+
                  |  3 | Fritz-3  | 2005-01-01 |
                  |  5 | Fritz-5  | 2007-02-01 |
                  |  1 | Fritz-1  | 2004-02-29 |
                  |  2 | Fritz-2  | 2008-02-29 |
                  |  6 | Fritz-6  | 2007-03-01 |
                  |  7 | Fritz-7  | 2007-04-01 |
                  |  8 | Fritz-8  | 2007-05-01 |
                  |  9 | Fritz-9  | 2007-06-01 |
                  | 10 | Fritz-10 | 2007-07-01 |
                  | 11 | Fritz-11 | 2007-08-01 |
                  | 12 | Fritz-12 | 2007-09-01 |
                  |  4 | Fritz-4  | 2004-12-31 |
                  +----+----------+------------+
                  12 rows in set (0.00 sec)
                  
                  mysql>

                  -- Ein Stored Procedure für die Logik
                  Code:
                  DELIMITER $$
                  CREATE FUNCTION BirthdayCheckLeapYear(dtDatum DATE) 
                   RETURNS CHAR(5) DETERMINISTIC
                  BEGIN
                   DECLARE sDatum CHAR(10);
                   DECLARE dtNewDate DATE;
                   
                   DECLARE sDatum29 CHAR(10); 
                   DECLARE dtNewDate29 DATE;
                   
                   SET sDatum = DATE_FORMAT(dtDatum, '%Y-%m-%d');
                   IF (substr(sDatum,6,5) = '02-29') THEN
                     -- Datum ist z.B '2008-02-29' => '2007-03-01'
                     SET dtNewDate = DATE_SUB(dtDatum, INTERVAL 1 YEAR); -- 28.02. xx
                     SET dtNewDate = DATE_ADD(dtNewDate, INTERVAL 1 DAY); -- 01.03. 
                   ELSEIF (substr(sDatum,6,5) = '03-01') THEN
                     -- Datum ist z.B '2009-03-01' => '2008-02-29'
                     SET dtNewDate = DATE_SUB(dtDatum, INTERVAL 1 YEAR);
                     SET dtNewDate29 = DATE_SUB(dtNewDate, INTERVAL 1 DAY);
                     SET sDatum29 = DATE_FORMAT(dtNewDate29, '%Y-%m-%d');
                     IF (substr(sDatum29,6,5) = '02-29') THEN
                      SET dtNewDate = dtNewDate29;
                     END IF;
                   ELSE
                     SET dtNewDate = DATE_SUB(dtDatum, INTERVAL 1 YEAR);
                   END IF;
                   
                   SET sDatum = DATE_FORMAT(dtNewDate, '%m-%d');
                   RETURN(sDatum);
                  END$$
                  DELIMITER ;
                  -- Test für den 01.03.
                  Code:
                  SELECT 1, id, name, gebtag, BirthdayCheckLeapYear(gebtag)
                    FROM geburtstag
                   WHERE gebtag < CURRENT_DATE()
                     AND BirthdayCheckLeapYear(gebtag) >= BirthdayCheckLeapYear('2010-03-01')
                     
                  UNION ALL 
                  
                  SELECT 2, id, name, gebtag, BirthdayCheckLeapYear(gebtag)
                    FROM geburtstag
                   WHERE gebtag < CURRENT_DATE()
                     AND BirthdayCheckLeapYear(gebtag) >= BirthdayCheckLeapYear('2010-01-01')  
                     
                  ORDER BY 1, 5
                  LIMIT 5;
                  
                  +---+----+---------+------------+-------------------------------+
                  | 1 | id | name    | gebtag     | BirthdayCheckLeapYear(gebtag) |
                  +---+----+---------+------------+-------------------------------+
                  | 1 |  6 | Fritz-6 | 2007-03-01 | 03-01                         |
                  | 1 |  1 | Fritz-1 | 2004-02-29 | 03-01                         |
                  | 1 |  2 | Fritz-2 | 2008-02-29 | 03-01                         |
                  | 1 |  7 | Fritz-7 | 2007-04-01 | 04-01                         |
                  | 1 |  8 | Fritz-8 | 2007-05-01 | 05-01                         |
                  +---+----+---------+------------+-------------------------------+
                  5 rows in set (0.02 sec)
                  
                  mysql>
                  -- Test für den 29.02.
                  Code:
                  SELECT 1, id, name, gebtag, BirthdayCheckLeapYear(gebtag)
                    FROM geburtstag
                   WHERE gebtag < CURRENT_DATE()
                     AND BirthdayCheckLeapYear(gebtag) >= BirthdayCheckLeapYear('2004-02-29')
                     
                  UNION ALL 
                  
                  SELECT 2, id, name, gebtag, BirthdayCheckLeapYear(gebtag)
                    FROM geburtstag
                   WHERE gebtag < CURRENT_DATE()
                     AND BirthdayCheckLeapYear(gebtag) >= BirthdayCheckLeapYear('2004-01-01')  
                     
                  ORDER BY 1, 5
                  LIMIT 5;
                  
                  +---+----+---------+------------+-------------------------------+
                  | 1 | id | name    | gebtag     | BirthdayCheckLeapYear(gebtag) |
                  +---+----+---------+------------+-------------------------------+
                  | 1 |  6 | Fritz-6 | 2007-03-01 | 03-01                         |
                  | 1 |  1 | Fritz-1 | 2004-02-29 | 03-01                         |
                  | 1 |  2 | Fritz-2 | 2008-02-29 | 03-01                         |
                  | 1 |  7 | Fritz-7 | 2007-04-01 | 04-01                         |
                  | 1 |  8 | Fritz-8 | 2007-05-01 | 05-01                         |
                  +---+----+---------+------------+-------------------------------+
                  5 rows in set (0.02 sec)

                  -- Test für den 31.12
                  Code:
                  SELECT 1, id, name, gebtag, BirthdayCheckLeapYear(gebtag)
                    FROM geburtstag
                   WHERE gebtag < CURRENT_DATE()
                     AND BirthdayCheckLeapYear(gebtag) >= BirthdayCheckLeapYear('2008-12-31')
                     
                  UNION ALL 
                  
                  SELECT 2, id, name, gebtag, BirthdayCheckLeapYear(gebtag)
                    FROM geburtstag
                   WHERE gebtag < CURRENT_DATE()
                     AND BirthdayCheckLeapYear(gebtag) >= BirthdayCheckLeapYear('2008-01-01')  
                     
                  ORDER BY 1, 5
                  LIMIT 5;
                  
                  +---+----+---------+------------+-------------------------------+
                  | 1 | id | name    | gebtag     | BirthdayCheckLeapYear(gebtag) |
                  +---+----+---------+------------+-------------------------------+
                  | 1 |  4 | Fritz-4 | 2004-12-31 | 12-31                         |
                  | 2 |  3 | Fritz-3 | 2005-01-01 | 01-01                         |
                  | 2 |  5 | Fritz-5 | 2007-02-01 | 02-01                         |
                  | 2 |  2 | Fritz-2 | 2008-02-29 | 03-01                         |
                  | 2 |  6 | Fritz-6 | 2007-03-01 | 03-01                         |
                  +---+----+---------+------------+-------------------------------+
                  5 rows in set (0.01 sec)
                  -- Test für das aktuelle Datum
                  Code:
                  SELECT 1, id, name, gebtag, BirthdayCheckLeapYear(gebtag)
                    FROM geburtstag
                   WHERE gebtag < CURRENT_DATE()
                     AND BirthdayCheckLeapYear(gebtag) >= BirthdayCheckLeapYear(CURRENT_DATE())
                     
                  UNION ALL 
                  
                  SELECT 2, id, name, gebtag, BirthdayCheckLeapYear(gebtag)
                    FROM geburtstag
                   WHERE gebtag < CURRENT_DATE()
                     AND BirthdayCheckLeapYear(gebtag) >= BirthdayCheckLeapYear(CONCAT(year(current_date), '-01-01'))  
                     
                  ORDER BY 1, 5
                  LIMIT 5;
                  +---+----+----------+------------+-------------------------------+
                  | 1 | id | name     | gebtag     | BirthdayCheckLeapYear(gebtag) |
                  +---+----+----------+------------+-------------------------------+
                  | 1 |  9 | Fritz-9  | 2007-06-01 | 06-01                         |
                  | 1 | 10 | Fritz-10 | 2007-07-01 | 07-01                         |
                  | 1 | 11 | Fritz-11 | 2007-08-01 | 08-01                         |
                  | 1 | 12 | Fritz-12 | 2007-09-01 | 09-01                         |
                  | 1 |  4 | Fritz-4  | 2004-12-31 | 12-31                         |
                  +---+----+----------+------------+-------------------------------+
                  5 rows in set (0.00 sec)
                  Hat jemand Lust, dass Ganze zu testen?

                  Grüße
                  Thomas

                  Kommentar

                  Lädt...
                  X