update Befehl mit select in where Bedingung

chris_9011

Benutzer
Beiträge
10
Hallo Zusammen,

ich bin Datenbankneueinsteiger mit ein bisschen Vorkenntissen und arbeite gerade an einer Datenbank.
manchmal sieht man den Wald vor lauter Bäumen nicht... deshalb wende ich mich an euch.

ich muss Werte in verschiedenen Tabellen dauerhaft aktualisieren, um mir nicht ständig die last insert id merken zu müssen habe ich mir folgenden Aufbau für den Update Query überlegt:


update `db`.`tabelle` set `time`='2015-04-22 10:57:10',ch1='0.000000',ch2='0.000000',ch3='0.000000',ch4='0.000000'
where `idtabelle` = (select max(`idtabelle`))

nun habe ich das Problem das alle in der Tabelle vorhandenen Einträge aktualisiert werden.
ich habe schon etwas gegoogelt, bin aber nicht wirklich auf die Ursache gekommen.

Kann mir jemand sagen wo ich da genau den Denkfehler habe?

Danke im Vorraus :)
 
Werbung:
ich muss Werte in verschiedenen Tabellen dauerhaft aktualisieren, um mir nicht ständig die last insert id merken zu müssen

Um sich einen Wert zu merken, kann man auch die DB verwenden. Möglicherweise ist diese weniger vergesslich als Du.

habe ich mir folgenden Aufbau für den Update Query überlegt:


update `db`.`tabelle` set `time`='2015-04-22 10:57:10',ch1='0.000000',ch2='0.000000',ch3='0.000000',ch4='0.000000'
where `idtabelle` = (select max(`idtabelle`))

Das sollte einen Syntaxfehler geben. Hoffe ich.

nun habe ich das Problem das alle in der Tabelle vorhandenen Einträge aktualisiert werden.
ich habe schon etwas gegoogelt, bin aber nicht wirklich auf die Ursache gekommen.

Kann mir jemand sagen wo ich da genau den Denkfehler habe?

Danke im Vorraus :)

  • Du sprichst erst von verschiedenen Tabellen, zeigst aber nur eine
  • mit max() an der Stelle zu arbeiten ist grundlegend falsch

Nutze das, was die DB Dir bietet. Das ist bei MySQL nicht viel, aber immer noch besser als es grundlegend falsch zu machen. Ich ahne grob, was Dein Problem ist - und kann Dir versichern, daß das in anderen Datenbanken nicht nur eleganter als in MySQL geht, sondern sogar in einem einzigen Statement / SQL und damit automatisch atomar.
 
Hallo akretschmer,

ich wollte nicht zu tief ins Detail gehen. Da mir ja in erster Linie nur der Aufbau des Querys und der Fehler am Herzen lag.
Ein Syntax Fehler kommt bei diesem Query nicht Zustande. --> die "Safe Update" option ist deaktiviert.
Die Tabellen haben alle den gleichen Aufbau wie im Query beschrieben, nur das pro Tabelle unterschiedliche viele Spalten vorhanden sein können.


In der Datenbank kann ich mir den letzen insert nicht merken, sonst spam ich den Server mit ständigen inserts/updates zu.

Was ist am Aufbau des Query falsch
Warum ist es falsch mit max() zu arbeiten?
 
Hallo akretschmer,

ich wollte nicht zu tief ins Detail gehen. Da mir ja in erster Linie nur der Aufbau des Querys und der Fehler am Herzen lag.
Ein Syntax Fehler kommt bei diesem Query nicht Zustande. --> die "Safe Update" option ist deaktiviert.

Was liefert

Code:
(select max(`idtabelle`))


Die Tabellen haben alle den gleichen Aufbau wie im Query beschrieben, nur das pro Tabelle unterschiedliche viele Spalten vorhanden sein können.

Hä?

In der Datenbank kann ich mir den letzen insert nicht merken, sonst spam ich den Server mit ständigen inserts/updates zu.

Hä?

Was ist am Aufbau des Query falsch

siehe oben.

Warum ist es falsch mit max() zu arbeiten?

Weil das eine Aggregatsfunktion ist. Um die letzte vergebene ID zu ermitteln gibt es andere Funktionen.
 
Code:
update tabelle_x set column_y = value_z where id = (select max(id))
Falsche Syntax. Was du eigentlich machen willst ist das:
Code:
update tabelle_x set column_y = value_z where id = (select max(id) from tabelle_x)
Problem dabei: MySQL lässt es nicht zu von der Tabelle, die man updaten möchte, in einem Sub-Select zu selektieren :)
 
Problem dabei: MySQL lässt es nicht zu von der Tabelle, die man updaten möchte, in einem Sub-Select zu selektieren :)

Danke Distrilec, das war eine klare Antwort! Wie sieht es da mit der Replace funktion aus?
 
Problem dabei: MySQL lässt es nicht zu von der Tabelle, die man updaten möchte, in einem Sub-Select zu selektieren :)

Wo ist das Problem. Ein einen Alias vergeben und schon gehts:

UPDATE City SET NAME ='Mein Name' WHERE id = (SELECT * FROM (SELECT max(id) FROM City ) AS tmp) ;

Gruss

Bernd
 
Hallo BerndB,

Gr0ßes Kino! vielen Dank!! Das hat mir viel Programmieraufwand erspart!
dürfte ich dir noch eine Frage bezüglich Indexe stellen oder muss ich dafür ein neues Thema eröffnen?
 
nice...

hier die Tabelle:

CREATE TABLE `device` (
`iddevice` int(11) NOT NULL AUTO_INCREMENT,
`time` datetime DEFAULT NULL,
`channel1` float DEFAULT NULL,
`channel2` float DEFAULT NULL,
`channel3` float DEFAULT NULL,
`channel4` float DEFAULT NULL,
PRIMARY KEY (`device`)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=latin1$$


in diese Tabelle werden Messwerte im 10 Sekundentakt oder über Events (also wenn z.b Messwert überschritten) geschrieben, ca 3Millionen pro Jahr.
Die am meisten benutzte WHERE Klausel liegt auf dem Feld `time` da man sich natürlich die Messwerte anschauen möchte.

1. Frage ist der Aufbau der Tabell dafur geeignet oder sollte man da was ändern?
2. ich habe einen Test mit 500.000 werten durchgeführt : select channel1 from db.device where `time` between 'x' and 'x' ergab : Duration 0.016 sec / Fetch 0,530 sec
danach habe ich einen Index auf das Feld `time` gelegt

ALTER TABLE `db`.`device`
ADD INDEX `index1` (`time` ASC) ;


und den Query nochmals ausgeführt (5 mal) und es ergab keine Differenz
der explain Befehl war unverändert.

my.ini

table_cache=256
tmp_table_size=18M
thread_cache_size=8
myisam_max_sort_file_size=100G
myisam_max_extra_sort_file_size=100G
myisam_sort_buffer_size=35M
key_buffer_size=25M
read_buffer_size=64K
read_rnd_buffer_size=256K
sort_buffer_size=256K
 
da, gibts noch einiges was man machen kann. Ich kann die Frage aber leider erst heute Abend beantworten.

Gruss

Bernd
 
in diese Tabelle werden Messwerte im 10 Sekundentakt oder über Events (also wenn z.b Messwert überschritten) geschrieben, ca 3Millionen pro Jahr.
Die am meisten benutzte WHERE Klausel liegt auf dem Feld `time` da man sich natürlich die Messwerte anschauen möchte.

1. Frage ist der Aufbau der Tabell dafur geeignet oder sollte man da was ändern?
2. ich habe einen Test mit 500.000 werten durchgeführt : select channel1 from db.device where `time` between 'x' and 'x' ergab : Duration 0.016 sec / Fetch 0,530 sec
danach habe ich einen Index auf das Feld `time` gelegt

ALTER TABLE `db`.`device`
ADD INDEX `index1` (`time` ASC) ;


und den Query nochmals ausgeführt (5 mal) und es ergab keine Differenz
der explain Befehl war unverändert.

Kommt immer drauf an, wie selektiv das WHERE ist. Bei anderen Datenbanken ist das Explain um Lichtjahre informativer, so nebenbei.
 
wie meinst du Selektiv? es wird ein ganz normaler select x from xy where x between (Zeitraum)

Tut mir leid ich nicht das nötige Know How an den Tag lege, aber wie am Anfang schon geschrieben bin ich Neueinsteiger
 
Werbung:
Zurück
Oben