MySQL - AKTUALISIEREN Sie mehrere Zeilen mit unterschiedlichen Werten in einer Abfrage

138

Ich versuche zu verstehen, wie man mehrere Zeilen mit unterschiedlichen Werten aktualisiert, und ich verstehe es einfach nicht. Die Lösung ist überall, aber für mich sieht es schwer zu verstehen aus.

Zum Beispiel drei Aktualisierungen in einer Abfrage:

UPDATE table_users
SET cod_user = '622057'
    , date = '12082014'
WHERE user_rol = 'student'
    AND cod_office = '17389551'; 

UPDATE table_users
SET cod_user = '2913659'
    , date = '12082014'
WHERE user_rol = 'assistant'
    AND cod_office = '17389551'; 

UPDATE table_users
SET cod_user = '6160230'
    , date = '12082014'
WHERE user_rol = 'admin'
    AND cod_office = '17389551'; 

Ich habe ein Beispiel gelesen , aber ich verstehe wirklich nicht, wie ich die Abfrage machen soll. dh:

UPDATE table_to_update
SET cod_user= IF(cod_office = '17389551','622057','2913659','6160230')
    ,date = IF(cod_office = '17389551','12082014')
WHERE ?? IN (??) ;

Ich bin mir nicht ganz sicher, wie ich die Abfrage durchführen soll, wenn die WHERE- und die IF-Bedingung mehrere Bedingungen enthalten.

franvergara66
quelle
Beantwortet das deine Frage? Mehrere Updates in MySQL
PeterPan666

Antworten:

186

Sie können es so machen:

UPDATE table_users
    SET cod_user = (case when user_role = 'student' then '622057'
                         when user_role = 'assistant' then '2913659'
                         when user_role = 'admin' then '6160230'
                    end),
        date = '12082014'
    WHERE user_role in ('student', 'assistant', 'admin') AND
          cod_office = '17389551';

Ich verstehe Ihr Datumsformat nicht. Daten sollten mit nativen Datums- und Uhrzeittypen in der Datenbank gespeichert werden.

Gordon Linoff
quelle
Wie kann ich das tun, damit das Update ausgeführt wird, wenn der Datensatz bereits existiert
franvergara66
1
@ franvergara66. . . Ich verstehe deinen Kommentar nicht. updates wirken sich nur auf bereits vorhandene Datensätze aus.
Gordon Linoff
Entschuldigen Sie meinen englischen Sir, wenn ich versuche, ein Update zu machen, geben Sie mir den Fehler: # 1062 - Doppelter Eintrag 'XXX' für Schlüssel 'PRIMARY'. Wenn ich versuche, einen Datensatz mit demselben Wert zu aktualisieren, den er bereits hatte, gibt es eine Möglichkeit, die Aktualisierung zu überspringen, wenn der aktuelle Wert mit dem aktualisierten Wert übereinstimmt?
franvergara66
1
@ franvergara66. . . Möglicherweise haben Sie ein anderes Problem. Wenn cod_useres sich um einen Primärschlüssel handelt und die Werte gemischt werden, sind mehrere Aktualisierungen wahrscheinlich die beste Route.
Gordon Linoff
1
Ja, ich verstehe, das eigentliche Problem ist, dass es mehrere Assistenten gibt. Wenn Sie dann versuchen, ein Update durchzuführen, wird die Integrität des Primärschlüssels verletzt. Vielen Dank für Ihre Zeit.
franvergara66
108

MySQL bietet eine besser lesbare Möglichkeit, mehrere Updates in einer einzigen Abfrage zu kombinieren. Dies scheint besser zu dem von Ihnen beschriebenen Szenario zu passen, ist viel einfacher zu lesen und vermeidet diese schwer zu entwirrenden Mehrfachbedingungen.

INSERT INTO table_users (cod_user, date, user_rol, cod_office)
VALUES
('622057', '12082014', 'student', '17389551'),
('2913659', '12082014', 'assistant','17389551'),
('6160230', '12082014', 'admin', '17389551')
ON DUPLICATE KEY UPDATE
 cod_user=VALUES(cod_user), date=VALUES(date)

Dies setzt voraus, dass die user_rol, cod_officeKombination ein Primärschlüssel ist. Wenn nur einer davon der Primärschlüssel ist , fügen Sie das andere Feld zur UPDATE-Liste hinzu. Wenn keiner von beiden ein Primärschlüssel ist (was unwahrscheinlich erscheint), werden bei diesem Ansatz immer neue Datensätze erstellt - wahrscheinlich nicht das, was gewünscht wird.

Dieser Ansatz macht es jedoch einfacher, vorbereitete Aussagen zu erstellen und präziser zu gestalten.

Trevedhek
quelle
4
Danke dir! Dies ist, wonach ich lange gesucht habe, auf die sauberste Art und Weise, ich konnte diese Syntax nicht herausfinden, insbesondere cod_user=VALUES(cod_user), ...nicht aus offiziellen MySQL 5.6-Dokumenten
Yuriy Dyachkov
18
Hinweis: Dadurch werden neue Zeilen hinzugefügt, wenn der Schlüssel nicht in der Tabelle vorhanden ist, was zu unerwünschten Datensätzen führt.
Faraz
1
Es ist schwierig, eine IODKU zu verwenden, die sich nie einfügt, aber dennoch sehr elegant.
Tom Desp
Beachten Sie, dass für diesen Ansatz ein Primärschlüssel für die Tabelle festgelegt werden muss.
FlameStorm
5
Dies funktioniert nicht, wenn Sie Spalten weglassen, die nicht null sein dürfen, da SQL immer noch versucht, einen neuen Datensatz zu erstellen, bevor tatsächlich auf die Aktualisierung zurückgegriffen wird.
Arno van Oordt
15

Sie können eine CASEAnweisung verwenden, um mehrere if / then-Szenarien zu behandeln:

UPDATE table_to_update 
SET  cod_user= CASE WHEN user_rol = 'student' THEN '622057'
                   WHEN user_rol = 'assistant' THEN '2913659'
                   WHEN user_rol = 'admin' THEN '6160230'
               END
    ,date = '12082014'
WHERE user_rol IN ('student','assistant','admin')
  AND cod_office = '17389551';
Hart CO
quelle
1
Sie haben am Ende der CASE-Anweisung einen Tippfehler gemacht: Sie haben 2 Kommas nebeneinander.
pmrotule
8
update table_name
set cod_user = 
    CASE 
    WHEN user_rol = 'student' THEN '622057'
    WHEN user_rol = 'assistant' THEN '2913659'
    WHEN user_rol = 'admin' THEN '6160230'?
    END,date = '12082014'

WHERE user_rol IN ('student','assistant','admin')
AND cod_office = '17389551';
Akshay Bhan
quelle
0

Um die Antwort von @Trevedhek zu erweitern ,

Falls das Update mit nicht eindeutigen Schlüsseln durchgeführt werden muss, sind 4 Abfragen erforderlich

HINWEIS: Dies ist nicht transaktionssicher

Dies kann mithilfe einer temporären Tabelle erfolgen.

Schritt 1: Erstellen Sie temporäre Tabellenschlüssel und die Spalten, die Sie aktualisieren möchten

CREATE TEMPORARY TABLE  temp_table_users
(
    cod_user varchar(50)
    , date varchar(50)
    , user_rol varchar(50)
    ,  cod_office varchar(50)
) ENGINE=MEMORY

Schritt 2: Fügen Sie die Werte in die temporäre Tabelle ein

Schritt 3: Aktualisieren Sie die ursprüngliche Tabelle

UPDATE table_users t1
JOIN temp_table_users tt1 using(user_rol,cod_office)
SET 
t1.cod_office = tt1.cod_office
t1.date = tt1.date

Schritt 4: Löschen Sie die temporäre Tabelle

Sab
quelle
0
UPDATE Table1 SET col1= col2 FROM (SELECT col2, col3 FROM Table2) as newTbl WHERE col4= col3

Hier sind col4 & col1 in Tabelle 1. col2 & col3 befinden sich in Tabelle 2.
Ich versuche, jedes col1 zu aktualisieren, wobei col4 = col3 für jede Zeile einen anderen Wert hat

Ankit Giri
quelle
-1

Ich habe es so gemacht:

<update id="updateSettings" parameterType="PushSettings">
    <foreach collection="settings" item="setting">
        UPDATE push_setting SET status = #{setting.status}
        WHERE type = #{setting.type} AND user_id = #{userId};
    </foreach>
</update>

wo PushSettings ist

public class PushSettings {

    private List<PushSetting> settings;
    private String userId;
}

es funktioniert gut

ru51an
quelle
Autor möchte 1 Abfrage, es ist klar, dass er es mit foreach tun kann, was mehrere Abfragen machen wird
Hristo93