การสลับค่าในคอลัมน์ด้วยคำสั่ง update เดียว


12

คุณพบว่าข้อผิดพลาดในระบบได้รับการตั้งชื่อผู้ชาย (M) ไม่ถูกต้องในฐานะผู้หญิง (W) และในทางกลับกันในฐานข้อมูล คอลัมน์อนุญาตสำหรับอักขระหนึ่งตัวเท่านั้น โดยไม่ต้องใช้ตาราง temp ใด ๆ ให้เขียนหนึ่งคิวรีอัปเดตเพื่อแก้ไข

คำถามนี้ถูกถามในการสัมภาษณ์เมื่อเร็ว ๆ นี้ที่ฉันมีและฉันจะไปสัมภาษณ์เพิ่มเติมที่อาจมีคำถามที่คล้ายกันดังนั้นฉันต้องการที่จะได้รับความคิดของวิธีการจัดการนี้


6
คุณถูกขอให้สมมติผลิตภัณฑ์ฐานข้อมูลเฉพาะหรือไม่ เช่น MySQL, SQL Server, Oracle, PostgreSQL ... ?
พอลไวท์ 9

ระบบของคุณอ่านแนวทางชุมชนใหม่หรือไม่? : \
AER

คำตอบ:


23

คุณต้องการใช้การCASEแสดงออกบางประเภท

ใน SQL Server รหัสจะเป็นดังนี้:

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

แก้ไข: ตามที่ระบุไว้ในความคิดเห็น (และคำตอบอื่น ๆ ) ELSE ไม่จำเป็นถ้าคุณใส่คำสั่งย่อย WHERE บนคำสั่ง

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

เป็นการหลีกเลี่ยงการอัพเดตที่ไม่จำเป็น สิ่งสำคัญไม่ว่าในกรณีใดก็คือให้จำไว้ว่ามีตัวเลือกอื่นนอกเหนือจาก M & W (เช่น NULL) และคุณไม่ต้องการใส่ข้อมูลที่ผิด ตัวอย่างเช่น:

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

สิ่งนี้จะแทนที่ NULL ใด ๆ (หรือเพศที่เป็นไปได้อื่น ๆ ) เป็น 'M' ซึ่งจะไม่ถูกต้อง


จะมีตัวเลือกอื่นสองสามอย่าง

/*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' );

และกระชับขึ้น

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

1
คุณสามารถแทนที่IIF()ด้วยIF()และมันจะทำงานใน MySQL;)
ypercubeᵀᴹ

9

ใน Oracle คุณสามารถใช้ CASE ได้ตามคำตอบอื่น ๆ :

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

คุณสามารถใช้ถอดรหัสได้:

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

5

สำหรับการสลับระหว่างสองค่าคุณสามารถลองใช้เคล็ดลับนี้ซึ่งไม่ใช้CASEนิพจน์ (สมมติว่า Transact-SQL ที่นี่):

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

ทั้งนี้ขึ้นอยู่กับมูลค่าปัจจุบันของGender, ASCII(Gender)จะยกเลิกการออกอย่างใดอย่างหนึ่งASCII('M')หรือASCII('W')ออกจากรหัสอื่น ๆ ที่จะเปลี่ยนแปลงโดยCHAR()ฟังก์ชั่นกลับไปที่ตัวอักษรที่สอดคล้องกัน

ฉันจะออกจากสิ่งนี้เพื่อการเปรียบเทียบเท่านั้น ในขณะที่ตัวเลือกนี้อาจมีข้ออ้างของความสง่างาม แต่การแก้ปัญหาโดยใช้CASEนิพจน์จะสามารถอ่านได้ง่ายขึ้นและง่ายต่อการบำรุงรักษาและแน่นอนว่าจะขยายได้ง่ายกว่าสองค่า


2
หวังว่าทั้งหมดMและWถูกป้อนในกรณีบนเพื่อหลีกเลี่ยงการที่ไม่คาดคิด7หรือ `- 'ปรากฏในผลลัพธ์
Martin Smith

@MartinSmith: จุดดีมาก หากพวกเขาไม่ได้เราจะต้องแทนที่ASCII(Gender)ด้วยASCII(UPPER(Gender))ซึ่งเป็นสง่าน้อยกว่าแม้ว่าจะไม่มาก
Andriy M

@MartinSmith ถ้ามีตัวพิมพ์เล็ก m และ w พวกเขาจะไม่ถูกปฏิเสธด้วยWHEREประโยค?
ypercubeᵀᴹ

1
@ YperSillyCubeᵀᴹ - เฉพาะในกรณีการตรวจเทียบที่ละเอียดอ่อน (ซึ่งไม่ใช่ IME ปกติ)
Martin Smith

4

คุณสามารถทำได้ด้วยcase ... whenนิพจน์:

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

ฉันจะใช้การอัปเดตพร้อมกับcaseนิพจน์

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

คุณสามารถทำการอัปเดตนี้โดยใช้caseนิพจน์

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

ฉันขอแนะนำให้เรียกใช้คำสั่งการปรับปรุงของคุณในการทำธุรกรรมและเพิ่มการสืบค้นง่ายๆเช่น:

SELECT n.gender, *
FROM names_table

เพื่อตรวจสอบผลลัพธ์ที่คุณจะได้รับ การทำธุรกรรมด้วยการย้อนกลับและเปลี่ยนเป็นการกระทำเมื่อผลลัพธ์ของคุณสอดคล้องกับสิ่งที่คุณคาดหวัง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.