MySQL - UPDATE Abfrage mit LIMIT

74

Ich möchte die Zeilen in meiner Tabelle von 1001 bis 1000 aktualisieren.

Ich habe es mit folgender Abfrage versucht:

UPDATE `oltp_db`.`users` SET p_id = 3 LIMIT 1001, 1000
  1. Dies gibt mir einen Syntaxfehler. Ist das richtig? mache ich hier einen Fehler
  2. Können wir das Update auf diese Weise einschränken?

Außerdem haben die Zeilen, die ich aktualisieren möchte, den Wert Null für die Spalte p_id mit dem Datentyp INTEGER. Aus diesem Grund kann ich nicht einmal mit folgender Abfrage aktualisieren:

UPDATE `oltp_db`.`users` SET p_id = 3 WHERE p_id = null
  1. Ist meine obige Abfrage korrekt?
  2. Was kann getan werden, um dies zu erreichen?
Rahul Shelke
quelle

Antworten:

28

Stimmt beim Umgang mit Null =nicht mit den Nullwerten überein. Sie können IS NULLoder verwendenIS NOT NULL

UPDATE `smartmeter_usage`.`users_reporting` 
SET panel_id = 3 WHERE panel_id IS NULL

LIMITkann mit UPDATEaber row countnur mit verwendet werden

Shakti Singh
quelle
Danke für die Antwort. Können Sie mir bitte einen Einblick geben, warum sich NULL von = null unterscheidet? Ebenfalls. Was genau macht IS NULL, um Nullwerte zu finden?
Rahul Shelke
2
@ srahul07: Weil NULL kein realer Wert ist und =auf Gleichheit zweier Werte prüfen. Daher =stimmt nicht mit null überein.
Shakti Singh
@Framework, Update-Limit mit row countnicht funktioniert für MySQL Version 5.1.X
Pragnesh Chauhan
130

Wenn Sie mehrere Zeilen mithilfe von limit in MySQL aktualisieren möchten, können Sie dieses Konstrukt verwenden:

UPDATE table_name SET name='test'
WHERE id IN (
    SELECT id FROM (
        SELECT id FROM table_name 
        ORDER BY id ASC  
        LIMIT 0, 10
    ) tmp
)
Roopchand
quelle
23
MySQL 5.5 unterstützt LIMIT in der Unterabfrage IN / ALL / ANY / SOME nicht: Fehlercode 1235
FiveO
9
@FiveO Funktioniert gut für mich unter MySQL 5.5.34. Ohne die verschachtelte Unterabfrage (das perverse SELECT id FROM (SELECT id FROM ...)Konstrukt) erhalte ich ERROR 1235 (42000): This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery', aber wenn ich beide Auswahlen wie hier gezeigt einbinde , funktioniert die Abfrage.
Mark Amery
2
Übrigens funktioniert diese Art von Code für Postgres 9.4, ohne dass der äußere SELECT id FROM (… benötigt wird ) tmp . Vielen Dank. Scheint so, als ob dies die akzeptierte Antwort sein sollte.
Basil Bourque
11

Ich würde eine zweistufige Abfrage vorschlagen

Ich gehe davon aus, dass Sie einen automatisch inkrementierenden Primärschlüssel haben, weil Sie sagen, dass Ihre PK (max + 1) ist, was wie die Definition eines automatisch inkrementierenden Schlüssels klingt.
Ich rufe die PK an id, ersetze sie durch die , die deine PK heißt.

1 - Ermitteln Sie die Primärschlüsselnummer für Spalte 1000.

SELECT @id:= id FROM smartmeter_usage LIMIT 1 OFFSET 1000

2 - Aktualisieren Sie die Tabelle.

UPDATE smartmeter_usage.users_reporting SET panel_id = 3 
WHERE panel_id IS NULL AND id >= @id 
ORDER BY id 
LIMIT 1000

Bitte testen Sie, ob ich keinen Fehler gemacht habe. Möglicherweise müssen Sie irgendwo 1 addieren oder subtrahieren.

Johan
quelle
8

Zusätzlich zu dem oben beschriebenen verschachtelten Ansatz können Sie die Anwendung der LIMITVerwendung JOINin derselben Tabelle ausführen:

UPDATE `table_name`
INNER JOIN (SELECT `id` from `table_name` order by `id` limit 0,100) as t2 using (`id`)
SET `name` = 'test'

Nach meiner Erfahrung ist der MySQL-Abfrageoptimierer mit dieser Struktur zufriedener.

Jerry
quelle
4
UPDATE `smartmeter_usage`.`users_reporting` SET panel_id = 3 LIMIT 1001, 1000

Diese Abfrage ist nicht korrekt (oder zumindest kenne ich keine Möglichkeit, Limit in UPDATE-Abfragen zu verwenden). Sie sollten eine whereBedingung für Ihren Primärschlüssel festlegen (dies setzt voraus, dass Sie eine auto_increment-Spalte als Primärschlüssel haben, falls nicht angegeben mehr Details):

UPDATE `smartmeter_usage`.`users_reporting` SET panel_id = 3 WHERE primary_key BETWEEN 1001 AND 2000

Für die zweite Abfrage müssen Sie IS verwenden

UPDATE `smartmeter_usage`.`users_reporting` SET panel_id = 3 WHERE panel_id is null

BEARBEITEN - Wenn Ihr Primärschlüssel eine Spalte mit dem Namen MAX + 1 ist, die Sie abfragen sollten (mit Backticks, wie im Kommentar korrekt angegeben):

UPDATE `smartmeter_usage`.`users_reporting` SET panel_id = 3 WHERE `MAX+1` BETWEEN 1001 AND 2000

So aktualisieren Sie die Zeilen mit MAX + 1 von 1001 auf 2000 (einschließlich 1001 und 2000)

Nicola Peluchetti
quelle
2
Sie gehen davon aus, dass er ein auto_increment in der Tabelle hat, was möglicherweise nicht der Fall ist und auch keine ununterbrochene Reihe von Zahlen sein muss.
jishi
Nun ja, natürlich mache ich diese Annahme, ich werde die Antwort damit aktualisieren und auf weitere Informationen warten! :)
Nicola Peluchetti
Danke für die Antwort. Eigentlich ist der Primärschlüssel MAX + 1.
Rahul Shelke
1
-1, (A) max ist ein reserviertes Wort, muss in Backticks angegeben werden. (B) max + 1 between 1001 and 2000sollte umgeschrieben werden max between 1000 and 1999. (C) Ich habe noch nie von einem Primärschlüssel gehört max+1, der keinen Sinn ergibt. (D) Dieser Code geht davon aus, dass die Spalte maxkontinuierlich ist, was in keiner Weise garantiert wird. (E) Limit funktioniert mit update.
Johan
Gute Antwort. Ihre erste UPDATE-Abfrage funktioniert perfekt, wenn Sie ein automatisches PK-Inkrement haben!
Deepcell
4

Sie können dies mit einem LIMIT tun, nur nicht mit einem LIMIT und einem OFFSET.

user945389
quelle
1

Sie sollten IS anstelle von = für den Vergleich mit NULL verwenden.

UPDATE `smartmeter_usage`.`users_reporting`
SET panel_id = 3
WHERE panel_id IS null

Die LIMITKlausel in MySQL, die auf ein Update angewendet wird, erlaubt keine Angabe eines Offsets.

Will A.
quelle
Dies hat mir in einer ähnlichen, aber anderen Situation geholfen - die Abfrage sollte lauten: "update my_table set process_id = n limit 1000" anstelle von "update my_table set process_id = n limit 0,1000"
rrrhys
0

Sie sollten in Betracht ziehen, ein zu verwenden, ORDER BYwenn Sie Ihr UPDATE BEGRENZEN möchten, da es sonst in der Reihenfolge der Tabelle aktualisiert wird, was möglicherweise nicht korrekt ist.

Aber wie Will A sagte, erlaubt es nur die Begrenzung von row_count, nicht den Offset.

Jishi
quelle
0

Für Leute erhalten Sie diesen Beitrag durch die Suche "Update Limit MySQL" versuchen, das Ausschalten zu vermeiden, safe update modewenn Sie updatemit der Syntax für mehrere Tabellen konfrontiert sind .

Seit dem offiziellen Dokument Zustand

Bei der Syntax für mehrere Tabellen aktualisiert UPDATE die Zeilen in jeder in table_references genannten Tabelle, die die Bedingungen erfüllen. In diesem Fall können ORDER BY und LIMIT nicht verwendet werden.

https://stackoverflow.com/a/28316067/1278112
Ich denke, diese Antwort ist sehr hilfreich. Es gibt ein Beispiel

UPDATE Kunden SET countryCode = 'USA' WHERE country = 'USA'; - was den Fehler gibt, schreiben Sie einfach:

UPDATE Kunden SET countryCode = 'USA' WHERE (country = 'USA' UND customerNumber <> 0); - Da customerNumber ein Primärschlüssel ist, haben Sie keinen Fehler mehr 1175 erhalten.

Was ich will, würde aber den Fehlercode 1175 auslösen.

UPDATE table1 t1
        INNER JOIN
    table2 t2 ON t1.name = t2.name 
SET 
    t1.column = t2.column
WHERE
    t1.name = t2.name;

Die Arbeitsausgabe

UPDATE table1 t1
        INNER JOIN
    table2 t2 ON t1.name = t2.name 
SET 
    t1.column = t2.column
WHERE
    (t1.name = t2.name and t1.prime_key !=0);

Welches ist wirklich einfach und elegant. Da die ursprüngliche Antwort nicht zu viel Aufmerksamkeit erhält (Stimmen), poste ich weitere Erklärungen. Hoffe das kann anderen helfen.

Shihe Zhang
quelle