Forum: PC-Programmierung MySQL-Frage: Neuesten Datensatz updaten


von Server-Neuling (Gast)


Lesenswert?

Moin,

wie kann ich in einer MySQL-Tabelle den (zeitlich) neuesten Eintrag 
updaten? Gibt es da eine Möglichkeit, das mit einer Abfrage 
hinzubekommen? Die betreffende Tabelle hat eine Spalte mit einem 
Zeitstempel.

Einzeln ist das klar:

Neuesten Datensatz finden: "SELECT * FROM tabelle ORDER by zeitstempel 
DESC LIMIT 1"

Datensatz ändern: "UPDATE tabelle SET spalte=wert WHERE ...?!"

Aber wie bekomme ich beides in eine Abfrage?

von Peter (Gast)


Lesenswert?

subselect?


UPDATE tabelle SET spalte=wert WHERE Zeitstempel = ( select max( 
Zeitstempel) from tabelle where ... )

von Server-Neuling (Gast)


Lesenswert?

Geht leider nicht:

Probiert habe ich:

"UPDATE status_log SET zeit=now() where zeit = (select zeit from 
status_log order by zeit desc limit 1)"

Ergebnis:

#1093 - Die Verwendung der zu aktualisierenden Zieltabelle 'status_log' 
ist in der FROM-Klausel nicht zulässig.

von Peter (Gast)


Lesenswert?

schade - das ist mysql scheinbar noch nicht so weit. (MS-SQL kann das).

du solltst aber wenn es denn gehen würde lieber Max und nicht limit 
verwenden. Max sollte etwas schnell sein.

von fbi (Gast)


Lesenswert?

Peter schrieb:
> Max sollte etwas schnell sein.

Bei MySQL bin ich mir da nicht so sicher :)

@Server-Neuling:
Versuchs mal mit
1
UPDATE status_log SET zeit=now() ORDER BY zeit DESC LIMIT 1;

von Peter (Gast)


Lesenswert?

fbi schrieb:
> UPDATE status_log SET zeit=now() ORDER BY zeit DESC LIMIT 1;

also wenn das geht, dann verliere komplett den glauben an mysql.

von fbi (Gast)


Lesenswert?

:)

direkt aus dem "MySQL Reference Manual for version 4.0.22":
1
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
2
    SET col_name1=expr1 [, col_name2=expr2 ...]
3
    [WHERE where_definition]
4
    [ORDER BY ...]
5
    [LIMIT row_count]

von Stefan W. (swesch)


Lesenswert?

Ich persönlich würde das anders lösen.

Die Tabelle status_log bekommt eine Spalte status_log_id als PrimaryKey.
Die Spalte ist dann integer oder größer.

Beim Insert kann dann die DB-Engine (autoidentity) selbst oder du in 
einer StoredProcedure diesen Wert inkrementieren und schreiben.

Auf diese Spalte wird auch der Hauptindex der Tabelle gelegt.

Beim Update auf den jüngsten Datensatz würde ich dann einen NestedSelect 
verwenden:
UPDATE bla bla WHERE Zeitstempel IN ( SELECT MAX(Zeitstempel)....)

Vorteil: Beim NestedSelect wird auf jeden Fall der Index verwendet und 
das ganze geht entsprechend schnell.

Bei dem internen ORDER BY & LIMIT und sehr großen Tabellen kann es sonst 
irgendwann knirschen und du musst dich mit den internen Zugriffsplänen 
rumschlagen.

HTH
Stefan

von Jens G. (jensig)


Lesenswert?

UPDATE tabelle SET spalte=wert WHERE Zeitstempel = max(Zeitstempel)

geht nicht?

von Peter (Gast)


Lesenswert?

Stefan W. schrieb:
> UPDATE bla bla WHERE Zeitstempel IN ( SELECT MAX(Zeitstempel)....)

die Idee war ja schon da, myssql kann scheinbar nicht das update und 
select gleichzeitg auf die gleiche Tabelle.

> #1093 - Die Verwendung der zu aktualisierenden Zieltabelle 'status_log'
> ist in der FROM-Klausel nicht zulässig

von Oliver H. (Firma: OliverHeinrichs.de) (dobson)


Lesenswert?

Gibt es da nicht was mit Last_inserted?

EDIT:
http://forums.mysql.com/read.php?12,2060,2060
Vielleicht hilft dir das ein wenig...

von Oliver H. (Firma: OliverHeinrichs.de) (dobson)


Lesenswert?

I'm sorry...
War der falsche Link... Den hier meinte ich:
http://dev.mysql.com/doc/refman/5.1/de/information-functions.html
Auf der Seite ungefähr in der Mitte.

von fbi (Gast)


Lesenswert?

LAST_INSERT_ID() nutzt hier garnichts, der als letztes eingefügte 
Datensatz muß ja nicht unbeding der "zeitlich neueste Eintrag" sein. Es 
gibt schließlich auch noch UPDAE Statements.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Man könnte natürlich auch einfach das ganze in eine Transaktion packen 
und in zwei Querys aufsplitten...

Was aber geht:
1
create view workaround as SELECT id as timeid from time_update order by time desc limit 1;
1
UPDATE time_update SET wert='hallo' WHERE id = (SELECT timeid FROM workaround);

Wie zuverlässig das ist oder ob es ggf. Seiteneffekte gibt weiß ich 
natürlich nicht.

Tabelle:
1
CREATE TABLE  `test`.`time_update` (
2
  `id` int(11) NOT NULL,
3
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
4
  `wert` varchar(200) NOT NULL,
5
  PRIMARY KEY (`id`)
6
) ENGINE=MyISAM DEFAULT CHARSET=latin1

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.