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

update Befehl mit select in where Bedingung

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von chris_9011, 22 April 2015.

  1. chris_9011

    chris_9011 Benutzer

    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 :)
     
  2. akretschmer

    akretschmer Datenbank-Guru

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

    Das sollte einen Syntaxfehler geben. Hoffe ich.

    • 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.
     
  3. chris_9011

    chris_9011 Benutzer

    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?
     
  4. akretschmer

    akretschmer Datenbank-Guru

    Was liefert

    Code:
    (select max(`idtabelle`))
    

    Hä?

    Hä?

    siehe oben.

    Weil das eine Aggregatsfunktion ist. Um die letzte vergebene ID zu ermitteln gibt es andere Funktionen.
     
  5. Distrilec

    Distrilec Datenbank-Guru

    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 :)
     
  6. chris_9011

    chris_9011 Benutzer

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

    BerndB Datenbank-Guru

    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
     
    chris_9011 gefällt das.
  8. chris_9011

    chris_9011 Benutzer

    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?
     
  9. BerndB

    BerndB Datenbank-Guru

    nö, mach doch
     
  10. chris_9011

    chris_9011 Benutzer

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

    BerndB Datenbank-Guru

    da, gibts noch einiges was man machen kann. Ich kann die Frage aber leider erst heute Abend beantworten.

    Gruss

    Bernd
     
  12. chris_9011

    chris_9011 Benutzer

    Ok, danke nochmal für deine schnelle Hilfe!!!
     
  13. akretschmer

    akretschmer Datenbank-Guru

    Kommt immer drauf an, wie selektiv das WHERE ist. Bei anderen Datenbanken ist das Explain um Lichtjahre informativer, so nebenbei.
     
  14. chris_9011

    chris_9011 Benutzer

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

    akretschmer Datenbank-Guru

    Wenn ein WHERE auf 99% der Tabelle paßt, ist ein Sequentieller Scan billiger als ein Indexscan. Wenn Dich das Thema interessiert, schaue Dir PostgreSQL und dessen kostenbasierten Optimizer an.
     
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