Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

MySQL Ver 8.0.22 for Linux: Datum berechnen von zwei Spalten

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von dbsven78, 30 November 2020.

  1. dbsven78

    dbsven78 Benutzer

    Ich habe die folgende Tabelle (NRW) erstellt (Datenbank heißt: Ministerpraesidenten):

    +-----------------+-----------+------+-----+---------+----------------+
    | Field | Type | Null | Key | Default | Extra |
    +-----------------+-----------+------+-----+---------+----------------+
    | nrw_id | int | NO | PRI | NULL | auto_increment |
    | Vorname | char(255) | NO | | NULL | |
    | Nachname | char(255) | NO | | NULL | |
    | Partei | char(100) | YES | | NULL | |
    | Amtszeit_Beginn | date | NO | | NULL | |
    | Amtszeit_Ende | date | NO | | NULL | |
    +-----------------+-----------+------+-----+---------+----------------+

    nrw_id | Vorname | Nachname | Partei | Amtszeit_Beginn | Amtszeit_Ende |
    +--------+-----------+-------------+---------+-----------------+---------------+
    | 1 | Rudolf | Amelunxen | Zentrum | 1946-08-30 | 1947-04-19 |
    | 2 | Karl | Arnold | CDU | 1947-06-16 | 1956-02-19 |
    | 3 | Fritz | Steinhoff | SPD | 1956-02-20 | 1958-07-20 |
    | 4 | Franz | Meyers | CDU | 1958-07-21 | 1966-12-07 |
    | 5 | Heinz | Kühn | SPD | 1966-12-08 | 1978-09-19 |
    | 6 | Johannes | Rau | SPD | 1978-09-20 | 1998-05-26 |
    | 7 | Wolfgang | Clement | SPD | 1998-05-27 | 2002-10-20 |
    | 8 | Michael | Vesper | Grüne | 2002-10-21 | 2002-11-05 |
    | 9 | Peer | Steinbrück | SPD | 2002-11-06 | 2005-06-21 |
    | 10 | Jürgen | Rüttgers | CDU | 2005-06-21 | 2010-07-14 |
    | 11 | Hannelore | Kraft | SPD | 2010-07-14 | 2017-06-27

    Ich möchte jetzt eine Zeitberechnung zwischen Amtszeit_Ende und Amtszeit_Beginn durchführen, die in einer neuen Spalte erscheint.

    Wenn ich den folgenden Befehl eingebe

    SELECT Nachname, Amtszeit_Beginn, Amtszeit_Ende, (TO_DAYS(Amtszeit_Ende)-TO_DAYS(Amtszeit_Beginn)) AS alter FROM NRW WHERE Amtszeit_Ende IS NOT NULL ORDER BY alter;

    ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'alter FROM NRW WHERE Amtszeit_Ende IS NOT NULL ORDER BY alter' at line 1

    oder

    SELECT Nachname Amtszeit_Ende Amtszeit_Beginn SYSDATE Amtszeit_Ende FROM NRW;
    ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Amtszeit_Beginn SYSDATE Amtszeit_Ende FROM NRW' at line 1

    Ich war auch im "Handbuch" von MySQL, aber da blicke ich leider nicht durch.

    Daher frage ich nun:
    Ist es möglich, dass man überhaupt die Zeit in dieser Form berechnet in MySQL so wie ich mir das vorstelle, Spaltenname Amtszeit_Ende - Amtszeit_Beginn, und wenn ja wie?

    Vielen Dank im Voraus
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Code:
    test=# create table dbseven78 (id int generated always as identity, von date, bis date);
    CREATE TABLE
    test=*# copy dbseven78 (von,bis) from stdin;
    Enter data to be copied followed by a newline.
    End with a backslash and a period on a line by itself, or an EOF signal.
    >> 2020-01-01   2020-08-01
    >> 2000-08-30    2020-11-30   
    >> \.
    COPY 2
    test=*# select * from dbseven78;
     id |    von     |    bis     
    ----+------------+------------
      1 | 2020-01-01 | 2020-08-01
      2 | 2000-08-30 | 2020-11-30
    (2 rows)
    test=*# select *, bis-von from dbseven78;
     id |    von     |    bis     | ?column?
    ----+------------+------------+----------
      1 | 2020-01-01 | 2020-08-01 |      213
      2 | 2000-08-30 | 2020-11-30 |     7397
    (2 rows)
    
    test=*# select *, bis-von as dauer from dbseven78 order by dauer;
     id |    von     |    bis     | dauer
    ----+------------+------------+-------
      1 | 2020-01-01 | 2020-08-01 |   213
      2 | 2000-08-30 | 2020-11-30 |  7397
    (2 rows)
    
    test=*# select *, bis-von as dauer from dbseven78 order by dauer desc;
     id |    von     |    bis     | dauer
    ----+------------+------------+-------
      2 | 2000-08-30 | 2020-11-30 |  7397
      1 | 2020-01-01 | 2020-08-01 |   213
    (2 rows)
    
    test=*#
    
    funktioniert also, allerdings kein MySQL.
     
  3. Walter

    Walter Administrator Mitarbeiter

    ALTER ist ein Schlüsselwort ("ALTER TABLE"), versuch den gleichen SELECT mit "dauer" so wie es mein Vorposter getan hat ohne Dir das zu verraten :) (hab es selber aber auch nicht ausprobiert)
     
  4. akretschmer

    akretschmer Datenbank-Guru

    nette idee ...

    Code:
    test=*# select *, bis-von as alter from dbseven78 order by alter desc;
     id |    von     |    bis     | alter
    ----+------------+------------+-------
      2 | 2000-08-30 | 2020-11-30 |  7397
      1 | 2020-01-01 | 2020-08-01 |   213
    (2 rows)
    
    test=*#
    
     
  5. dabadepdu

    dabadepdu Datenbank-Guru

    Ja, das ist wohl geklärt. Dann noch:
    - NRW ID klingt so, als gäbe es auch eine BW_ID. eine HH_ID usw. also je Bundesland eine Tabelle, sowas macht man nicht. Die Dimension Bundesland gehört in eine Spalte, alles in eine Tabelle.

    Ansonsten hoffe ich, dass die armen Kerls nicht schon von Geburt an Präsident sein mussten, würde allerdings die ein oder andere Kindische Geschichte erklären.
    ;)
    ALTER ist also nicht unbedingt die beste Wahl für diesen Spalten Alias.
     
  6. dbsven78

    dbsven78 Benutzer

    ich bekomme beim Befehl:

    copy NRW (Amtszeit_Beginn,Amtszeit_Ende) FROM stdin;
    ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'copy NRW (Amtszeit_Beginn,Amtszeit_Ende) FROM stdin' at line 1

    eine Fehlermeldung.


    Außerdem:

    mysql> SELECT *, Amtszeit_Ende - Amtszeit_Beginn AS Dauer from NRW;
    +--------+-----------+-------------+---------+-----------------+---------------+--------+
    | nrw_id | Vorname | Nachname | Partei | Amtszeit_Beginn | Amtszeit_Ende | Dauer |
    +--------+-----------+-------------+---------+-----------------+---------------+--------+
    | 1 | Rudolf | Amelunxen | Zentrum | 1946-08-30 | 1947-04-19 | 9589 |
    | 2 | Karl | Arnold | CDU | 1947-06-16 | 1956-02-19 | 89603 |
    | 3 | Fritz | Steinhoff | SPD | 1956-02-20 | 1958-07-20 | 20500

    Das kann es nicht sein. Vor allem der erste Wert bei Dauer muss weniger als 365 Tage sein.
     
  7. akretschmer

    akretschmer Datenbank-Guru

    Der COPY-Befehl funktioniert nicht unter MySQL, ich nutze PostgreSQL.

    Code:
    test=*# select '1947-04-19'::date - '1946-08-30'::date;
     ?column?
    ----------
          232
    (1 row)
    
    Möglicherweise kann MySQL nicht mit Datumswerten rechnen. Ist ja auch kompliziert ...
     
  8. dbsven78

    dbsven78 Benutzer

    Ich habe die Tabelle inzwischen erweitert (auf Anraten von dabadepdu) bzw. umbenannt MP_id anstatt nrw_id.

    SELECT * FROM NRW;
    +-------+-----------+-------------+---------+-----------------+---------------+------------+
    | MP_id | Vorname | Nachname | Partei | Amtszeit_Beginn | Amtszeit_Ende | Bundesland |
    +-------+-----------+-------------+---------+-----------------+---------------+------------+
    | 1 | Rudolf | Amelunxen | Zentrum | 1946-08-30 | 1947-04-19 | NRW

    Im Prinzip kann MySQL schon:

    MySQL :: MySQL 8.0 Reference Manual :: 12.7 Date and Time Functions

    SELECT DATEDIFF('1947-04-19','1946-08-30'); = 232

    Das Ergebnis stimmt, denn ich habe es in einer Tabellenkalkulation nachgerechnet.


    Wenn ich den folgenden Befehl eingebe:

    SELECT Vorname, Nachname, DATEDIFF('Amtszeit_Ende','Amtszeit_Beginn') AS Dauer FROM NRW WHERE MP_id=1;
    +---------+-----------+-------+
    | Vorname | Nachname | Dauer |
    +---------+-----------+-------+
    | Rudolf | Amelunxen | NULL |
    +---------+-----------+-------+
    1 row in set, 2 warnings (0.00 sec)

    mysql> show warnings;
    +---------+------+---------------------------------------------+
    | Level | Code | Message |
    +---------+------+---------------------------------------------+
    | Warning | 1292 | Incorrect datetime value: 'Amtszeit_Ende' |
    | Warning | 1292 | Incorrect datetime value: 'Amtszeit_Beginn' |
    +---------+------+---------------------------------------------+
    2 rows in set (0.00 sec)


    DESCRIBE NRW;
    +-----------------+-----------+------+-----+---------+----------------+
    | Field | Type | Null | Key | Default | Extra |
    +-----------------+-----------+------+-----+---------+----------------+
    | MP_id | int | NO | PRI | NULL | auto_increment |
    | Vorname | char(255) | NO | | NULL | |
    | Nachname | char(255) | NO | | NULL | |
    | Partei | char(100) | YES | | NULL | |
    | Amtszeit_Beginn | date | NO | | NULL | |
    | Amtszeit_Ende | date | NO | | NULL | |
    | Bundesland | char(255) | YES | | NULL |

    Ist "date" nicht das korrekte Value für ein Datum?
     
  9. akretschmer

    akretschmer Datenbank-Guru

    vielleicht will es einen TIMESTAMP. Hat MySQL denn keine Doku für sowas?
     
  10. dbsven78

    dbsven78 Benutzer

    Timestamp gibt es, aber da führt nach meinem Wissen jetzt nicht weiter. Weil die Definition, die ich vom TIMESTAMP herkenne, ist die, dass TIMESTAMP benutzt wird, wenn man einen Eintrag macht, dass man dann sehen kann, wann der Eintrag gemacht worden ist. Das ist aber hier ja nicht der Fall, denn die Datumsangaben liegen ja schon weit in der Vergangenheit zum Teil.

    Ich glaube, ich muss noch anderweitig nachschauen oder es hat jemand anderes hier noch eine Idee, der MySQL auch benutzt (beruflich oder privat)?

    Aber ich bedanke trotzdem für deine Hilfe akretschmer
     
  11. akretschmer

    akretschmer Datenbank-Guru

    du verwechselst da was. Man kann bei einem Timestamp natürlich als default now() definieren, man kann aber auch einen Timestamp angeben:

    Code:
    test=*# create table dbsven78(id int generated always as identity, ts timestamp);
    CREATE TABLE
    test=*# insert into dbsven78 (ts) values ('1990-07-23 11:23:45');
    INSERT 0 1
    test=*#
    
     
  12. BerndB

    BerndB Datenbank-Guru

    Hallo,

    du musst nur die Feldnamen in Backticks setzen wenn du reservierte Worte als Spaltennamen nehmen möchtest.

    Code:
    SELECT Nachname, Amtszeit_Beginn, Amtszeit_Ende, 
    (TO_DAYS(Amtszeit_Ende)-TO_DAYS(Amtszeit_Beginn)) AS `alter` 
    FROM NRW WHERE Amtszeit_Ende IS NOT NULL 
    ORDER BY `alter`;

    Code:
    MariaDB [bernd]> SELECT Nachname, Amtszeit_Beginn, Amtszeit_Ende, (TO_DAYS(Amtszeit_Ende)-TO_DAYS(Amtszeit_Beginn)) AS `alter` FROM NRW WHERE Amtszeit_Ende IS NOT NULL ORDER BY `alter`;
    +-----------+-----------------+---------------+-------+
    | Nachname  | Amtszeit_Beginn | Amtszeit_Ende | alter |
    +-----------+-----------------+---------------+-------+
    | Amelunxen | 1946-08-30      | 1947-04-19    |   232 |
    +-----------+-----------------+---------------+-------+
    1 row in set (0.00 sec)
    
    MariaDB [bernd]>
    Gruß

    Bernd
     
    dbsven78 gefällt das.
  13. dbsven78

    dbsven78 Benutzer

    Yeah, das hat funktioniert. Danke Bernd. :)
     
  14. BerndB

    BerndB Datenbank-Guru

    Schön,

    nur als Info. Du kannst auch DATEDIFF zur Berechnung nehmen.

    Code:
     SELECT Nachname, Amtszeit_Beginn, Amtszeit_Ende,
    DATEDIFF(Amtszeit_Ende,Amtszeit_Beginn) AS `alter`
    FROM NRW WHERE Amtszeit_Ende IS NOT NULL
    ORDER BY `alter`;
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden