MySQL Ver 8.0.22 for Linux: Datum berechnen von zwei Spalten

dbsven78

Benutzer
Beiträge
5
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
 
Werbung:
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.
 
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)
 
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=*#
 
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.
 
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.

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.
 
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 ...
 
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 ...

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?
 
vielleicht will es einen TIMESTAMP. Hat MySQL denn keine Doku für sowas?
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
 
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=*#
 
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
 
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

Yeah, das hat funktioniert. Danke Bernd. :)
 
Werbung:
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`;
 
Zurück
Oben