Bir güncelleme ifadesi ile bir sütundaki değerleri değiştirme


12

Bir sistemdeki bir hatanın erkekleri (M) kadın (W) olarak yanlış adlandırdığını ve veritabanında tersini görüyorsunuz. Sütunlar yalnızca bir karaktere izin verir. Geçici tablo kullanmadan, bu sorunu çözmek için bir güncelleme sorgusu yazın.

Bu soru son zamanlarda yaptığım bir röportajda soruldu ve benzer soruları olabilecek daha fazla röportaj yapacağım, bu yüzden bunun nasıl ele alınacağı hakkında bir fikir edinmek istedim.


6
Belirli bir veritabanı ürününü varsaymanız istendi mi? örneğin MySQL, SQL Server, Oracle, PostgreSQL ...?
Paul White 9

Sisteminiz yeni topluluk kurallarını okudu mu? : \
AER

Yanıtlar:


23

Bir CASEtür ifade kullanmak istiyorsunuz .

SQL Server'da kod şöyle görünecektir:

UPDATE TableName
SET gender = CASE WHEN gender = 'M' THEN 'W' 
                  WHEN gender = 'W' THEN 'M'
                  ELSE gender END

Düzenleme: Yorumlar (ve diğer bazı cevaplar) belirtildiği gibi ELSE ifadeye bir WHERE yan tümcesi koyarsanız gerekli değildir.

UPDATE TableName
SET gender = CASE WHEN gender = 'M' THEN 'W' 
                  WHEN gender = 'W' THEN 'M' END
WHERE gender IN ('M','W')

Bu gereksiz güncellemeleri önler. Her iki durumda da önemli olan, M & W (örneğin NULL) dışında seçenekler olduğunu ve yanlış bilgi vermek istemediğinizi hatırlamaktır. Örneğin:

UPDATE TableName
SET gender = CASE WHEN gender = 'M' THEN 'W' 
                  ELSE 'M' END

Bu, NULL'lerin (veya diğer olası cinsiyetlerin) yanlış olan 'M' olarak değiştirilir.


Birkaç seçenek daha

/*Simple form of CASE rather than Searched form*/
UPDATE TableName
SET    gender = CASE gender
                  WHEN 'M' THEN 'W'
                  WHEN 'W' THEN 'M'
                END
WHERE  gender IN ( 'M', 'W' );

Ve daha özlü

/*For SQL Server 2012+*/
UPDATE TableName
SET    gender = IIF(gender = 'M', 'W', 'M')
WHERE  gender IN ( 'M', 'W' ); 

1
Sen yerini alabilecek IIF()olan IF()ve MySQL çalışacak;)
ypercubeᵀᴹ

9

Oracle'da, diğer yanıtların sahip olduğu gibi bir CASE kullanabilirsiniz:

UPDATE TableName
SET gender = CASE WHEN gender = 'M' THEN 'W' 
                  WHEN gender = 'W' THEN 'M'
             END
WHERE gender in ('M','W');

Bir DECODE da kullanabilirsiniz:

UPDATE TableName SET gender = DECODE(gender,'M','W','W','M')
WHERE gender in ('M','W');

5

Yalnızca iki değer arasında geçiş yapmak için, bir CASEifade kullanmayan bu hileyi de deneyebilirsiniz (burada Transact-SQL varsayarsak):

UPDATE
  YourTable
SET
  Gender = CHAR(ASCII('M') + ASCII('W') - ASCII(Gender))
WHERE
  Gender IN ('M', 'W')
;

Mevcut değerine bağlı olarak Gender, ASCII(Gender)ya iptal edecek ASCII('M')ya ASCII('W')değişin için başka kod bırakarak CHAR()gelen karaktere fonksiyon arka.

Bunu sadece karşılaştırma için bırakıyorum. Bu seçeneğin bir zerafeti olsa da, bir CASEifade kullanan bir çözüm tartışmalı olarak daha okunabilir ve böylece bakımı daha kolay olacaktır ve ikiden fazla değere genişletilmesi kesinlikle daha kolay olacaktır.


2
Umarız sonuçlarda beklenmedik veya `-` görünmesini önlemek için tüm Mve Wbüyük harflerle girilmiştir 7.
Martin Smith

@MartinSmith: Çok iyi bir nokta. Eğer olmasaydı, çok fazla olmasa da, daha az zarif olan ASCII(Gender)ile değiştirmeliyiz ASCII(UPPER(Gender)).
Andriy M

@MartinSmith küçük harf m ve w'ler varsa, bu WHEREmadde tarafından reddedilmeyecekler mi?
ypercubeᵀᴹ

1
@ YperSillyCubeᵀᴹ - Yalnızca hassas harmanlamalarda (bu her zamanki IME değildir)
Martin Smith

4

Bunu bir case ... whenifade ile yapabilirsiniz :

mysql> select * from genderswap;
+--------+
| gender |
+--------+
| F      |
| F      |
| M      |
| M      |
| M      |
| M      |
| M      |
+--------+
7 rows in set (0.00 sec)

mysql> 
mysql> UPDATE genderswap SET gender = case 
    ->                                when gender='M' then 'F' 
    ->                                when gender='F' then 'M'
    ->                                end
    -> WHERE gender IN ('M', 'F');
Query OK, 7 rows affected (0.00 sec)
Rows matched: 7  Changed: 7  Warnings: 0

mysql> 
mysql> select * from genderswap;
+--------+
| gender |
+--------+
| M      |
| M      |
| F      |
| F      |
| F      |
| F      |
| F      |
+--------+
7 rows in set (0.00 sec)

mysql> 

2

Ben bir caseifade ile bir güncelleme kullanırdım .

DECLARE @Test TABLE
    (
      Name VARCHAR(100) NULL
    , Gender CHAR(1) NULL
    );

INSERT  INTO @Test
        ( Name, Gender )
VALUES  ( 'Jonathan', 'W' )
         ,
        ( 'Kelly', 'M' );

SELECT  Name
      , Gender
FROM    @Test;

UPDATE  @Test
SET     Gender = CASE WHEN Gender = 'M' THEN 'W'
                      ELSE 'M'
                 END;

SELECT  Name
      , Gender
FROM    @Test;

-1

Bu güncelleştirmeyi bir caseifade kullanarak gerçekleştirebilirsiniz .

UPDATE names_table
   SET names_table.gender = ( CASE
                                  WHEN names_table.gender = 'M'
                                    THEN 'W'
                                  ELSE
                                      names_table.gender = 'M'
                              END)

Güncelleme ifadenizi bir işlemde çalıştırmanızı ve aşağıdaki gibi basit bir sorgu eklemenizi öneririm:

SELECT n.gender, *
FROM names_table

elde edeceğiniz sonuçları kontrol etmek için. İşlemi bir geri alma işlemiyle gerçekleştirme ve sonuçlarınız beklediğinizle aynı hizaya geldiğinde işlemi bir işleme geçirme

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.