MySQL - CẬP NHẬT nhiều hàng với các giá trị khác nhau trong một truy vấn


138

Tôi đang cố gắng hiểu làm thế nào để CẬP NHẬT nhiều hàng với các giá trị khác nhau và tôi không nhận được nó. Giải pháp ở khắp mọi nơi nhưng với tôi có vẻ khó hiểu.

Ví dụ: ba cập nhật thành 1 truy vấn:

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'; 

Tôi đã đọc một ví dụ, nhưng tôi thực sự không hiểu làm thế nào để thực hiện truy vấn. I E:

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

Tôi không hoàn toàn rõ ràng làm thế nào để thực hiện truy vấn nếu có nhiều điều kiện trong WHERE và trong điều kiện IF..nhiều ý tưởng?


Điều này có trả lời câu hỏi của bạn không? Nhiều cập nhật trong MySQL
PeterPan666

Câu trả lời:


186

Bạn có thể làm theo cách này:

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';

Tôi không hiểu định dạng ngày của bạn. Ngày nên được lưu trữ trong cơ sở dữ liệu bằng cách sử dụng các loại ngày và giờ gốc.


Làm thế nào tôi có thể làm để cập nhật được thực thi, nếu bản ghi đã tồn tại
franvergara66

1
@ franvergara66. . . Tôi không hiểu bình luận của bạn. updates chỉ ảnh hưởng đến hồ sơ đã tồn tại.
Gordon Linoff

Xin lỗi, tiếng anh của tôi, khi tôi cố gắng tạo một bản cập nhật mysql cho tôi biết lỗi: # 1062 - Mục nhập trùng lặp 'XXX' cho khóa 'CHÍNH HÃNG'. Điều đó xảy ra khi tôi cố gắng cập nhật một bản ghi có cùng giá trị đã có, có cách nào để bỏ qua bản cập nhật nếu giá trị hiện tại giống như được cập nhật không?
franvergara66

1
@ franvergara66. . . Bạn có thể có một vấn đề khác. Nếu cod_userlà một khóa chính và các giá trị đang bị xáo trộn xung quanh, thì nhiều bản cập nhật có lẽ là con đường tốt nhất.
Gordon Linoff

1
vâng, tôi hiểu rồi, vấn đề thực sự là có một vài trợ lý, sau đó khi cố gắng thực hiện cập nhật, tính toàn vẹn của khóa chính bị vi phạm. Cảm ơn vi đa danh thơi gian cho tôi.
franvergara66

108

MySQL cho phép một cách dễ đọc hơn để kết hợp nhiều bản cập nhật thành một truy vấn duy nhất. Điều này có vẻ phù hợp hơn với kịch bản bạn mô tả, dễ đọc hơn nhiều và tránh những điều kiện khó giải quyết đó.

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)

Điều này giả định rằng sự user_rol, cod_officekết hợp là một khóa chính. Nếu chỉ một trong số này là khóa chính , thì hãy thêm trường khác vào danh sách CẬP NHẬT. Nếu cả hai không phải là khóa chính (điều đó dường như không thể) thì cách tiếp cận này sẽ luôn tạo ra các bản ghi mới - có thể không phải là điều muốn.

Tuy nhiên, cách tiếp cận này làm cho các tuyên bố được chuẩn bị dễ dàng hơn để xây dựng và ngắn gọn hơn.


4
Cảm ơn bạn! Đây là những gì tôi đã tìm kiếm trong một thời gian dài, cách nhìn rõ ràng nhất, tôi không thể tìm ra cú pháp này, đặc biệt cod_user=VALUES(cod_user), ..., ngay cả từ các tài liệu chính thức của MySQL 5.6
Yuriy Dyachkov

18
Lưu ý: Điều này sẽ thêm các hàng mới nếu khóa không tồn tại trong bảng dẫn đến các bản ghi không mong muốn.
Faraz

1
Lừa để sử dụng IODKU không bao giờ chèn, nhưng rất thanh lịch.
Tom Desp

Và lưu ý rằng phương pháp này yêu cầu khóa chính được đặt cho bảng.
FlameStorm

5
Điều này không hoạt động nếu bạn bỏ qua bất kỳ cột nào không thể rỗng, vì sql vẫn cố gắng tạo bản ghi mới trước khi thực sự dùng đến cập nhật.
Arno van Oordt

15

Bạn có thể sử dụng một CASEcâu lệnh để xử lý nhiều kịch bản if / then:

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';

1
Bạn đã mắc lỗi đánh máy ở cuối câu lệnh CASE: bạn có 2 dấu phẩy cạnh nhau.
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';

0

Để mở rộng câu trả lời @Trevedhek ,

Trong trường hợp cập nhật phải được thực hiện với các khóa không phải là duy nhất, sẽ cần 4 truy vấn

LƯU Ý: Đây không phải là giao dịch an toàn

Điều này có thể được thực hiện bằng cách sử dụng một bảng tạm thời.

Bước 1: Tạo một phím bảng temp và các cột bạn muốn cập nhật

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

Bước 2: Chèn các giá trị vào bảng tạm thời

Bước 3: Cập nhật bảng gốc

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

Bước 4: Thả bảng tạm thời


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

Ở đây col4 & col1 nằm trong Bảng1. col2 & col3 nằm trong Bảng 2
Tôi đang cố gắng cập nhật mỗi col1 trong đó col4 = col3 có giá trị khác nhau cho mỗi hàng


-1

Tôi đã làm nó theo cách này:

<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>

PushSinstall ở đâu

public class PushSettings {

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

nó hoạt động tốt


tác giả muốn 1 truy vấn, rõ ràng anh ta có thể làm điều đó với foreach, sẽ thực hiện một số truy vấn
Hristo93
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.