MySQL - Bir sorguda farklı değerlere sahip birden çok satırı UPDATE


140

Farklı değerlere sahip birden çok satırı GÜNCELLEMEYİ anlamaya çalışıyorum ve sadece anlamıyorum. Çözüm her yerde ama benim için anlamak zor görünüyor.

Örneğin, 1 sorguda üç güncelleme:

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

Ben okumak bir örnek, ama gerçekten sorgu nasıl anlamıyorum. yani:

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

NEREDE ve EĞER durumunda birden fazla koşul varsa sorgu yapmak nasıl tamamen açık değilim ... herhangi bir fikir?


Bu sorunuza cevap veriyor mu?
MySQL'de

Yanıtlar:


189

Bunu şu şekilde yapabilirsiniz:

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

Tarih biçiminizi anlamıyorum. Tarihler, yerel tarih ve saat türleri kullanılarak veritabanında saklanmalıdır.


zaten kayıt varsa güncelleştirme
yürütmek için

1
@ franvergara66. . . Yorumunu anlamıyorum. updateyalnızca var olan kayıtları etkiler.
Gordon Linoff

Bir güncelleme mysql bana hata vermek için çalıştığınızda benim ingilizce efendim bahane: # 1062 - Anahtar 'PRIMARY' için yinelenen giriş 'XXX'. Bir kaydı zaten sahip olduğu değerle güncellemeye çalıştığımda, geçerli değer güncellenmeyle aynı ise güncellemeyi atlamanın herhangi bir yolu var mı?
franvergara66

1
@ franvergara66. . . Farklı bir sorununuz olabilir. Eğer cod_userbirincil anahtar ve değerler karıştırılmaz ediliyor, sonra birden fazla güncellemeler muhtemelen en iyi yoldur.
Gordon Linoff

1
evet, görüyorum, asıl sorun birkaç asistan var, o zaman bir güncelleme yapmaya çalışırken, birincil anahtarın bütünlüğü ihlal ediliyor. Zaman ayırdığınız için çok teşekkürler.
franvergara66

109

MySQL, birden fazla güncellemeyi tek bir sorguda birleştirmek için daha okunabilir bir yol sağlar. Bu, tanımladığınız senaryoya daha iyi uyuyor gibi görünüyor, okunması çok daha kolay ve çözülmesi zor çoklu durumlardan kaçınıyor.

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)

Bu, user_rol, cod_officekombinasyonun birincil anahtar olduğunu varsayar . Bunlardan yalnızca biri birincil anahtarsa , diğer alanı GÜNCELLEME listesine ekleyin. Her ikisi de birincil bir anahtar değilse (olası görünmüyorsa) bu yaklaşım her zaman yeni kayıtlar yaratacaktır - muhtemelen istenen şey değil.

Bununla birlikte, bu yaklaşım hazırlanmış ifadelerin oluşturulmasını ve daha özlü olmasını sağlar.


4
Teşekkür ederim! Uzun zamandır aradığım şey bu, en temiz görünümlü yol, bu sözdizimini, özellikle cod_user=VALUES(cod_user), ...resmi MySQL 5.6 belgelerinden bile anlayamadım
Yuriy Dyachkov

18
Not: Anahtar tabloda yoksa, istenmeyen kayıtlara neden olan yeni satırlar eklenir.
Faraz

1
Asla yerleştirilmeyen bir IODKU kullanmak zordur, ancak çok zariftir.
Tom Desp

Ve bu yaklaşım olduğunu not gerektiren birincil anahtar tablo için ayarlanır.
FlameStorm

5
Sql güncellemeye başvurmadan önce yeni kayıt oluşturmaya çalıştığından, boş olamaz sütunları atlarsanız bu işe yaramaz.
Arno van Oordt

15

CASEBirden fazla if / then senaryosunu işlemek için bir ifade kullanabilirsiniz :

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
CASE ifadesinin sonunda bir yazım hatası yaptınız: yan yana 2 virgül var.
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

@Trevedhek cevabını genişletmek için ,

Güncellemenin benzersiz olmayan anahtarlarla yapılması gerekiyorsa, 4 sorgu gerekli olacaktır

NOT: Bu işlem için güvenli değildir

Bu bir geçici tablo kullanılarak yapılabilir.

1. Adım: Geçici tablo anahtarları ve güncellemek istediğiniz sütunları oluşturun

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

2. Adım: Değerleri geçici tabloya ekleyin

3. Adım: Orijinal tabloyu güncelleyin

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

Adım 4: Temp tablosunu bırakın


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

Burada col4 ve col1 Tablo1'de yer almaktadır. col2 & col3
Tablo2'de


-1

Bu şekilde yaptım:

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

PushSettings nerede

public class PushSettings {

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

iyi çalışıyor


yazar 1 sorgu istiyor, o birkaç sorgu yapacak foreach ile yapabilirsiniz açıktır
Hristo93
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.