web-dev-qa-db-ja.com

1つの更新ステートメントで列の値を切り替える

システムのエラーにより、データベースで男性(M)が女性(W)に、またはその逆に誤って命名されていることがわかりました。列には1文字しか入力できません。一時テーブルを使用せずに、これを解決する更新クエリを1つ記述します。

この質問は、私が最近行ったインタビューで尋ねられました。同様の質問がある可能性があるインタビューをさらに検討しているので、これをどのように処理するかについてのアイデアを得たいと思いました。

12
SethYes

あるタイプのCASE式を使用したい。

SQL Serverでは、コードは次のようになります。

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

編集:コメント(および他のいくつかの回答)に記載されているように、ステートメントにWHERE句を指定する場合、ELSEは必要ありません。

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' ); 
23
Kenneth Fisher

Oracleでは、他の答えがあるようにCASEを使用できます:

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

DECODEを使用することもできます。

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

2つの値のみを切り替えるには、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式を使用したソリューションは間違いなく読みやすく、保守が容易であり、3つ以上の値に展開する方が間違いなく簡単です。

5
Andriy M

あなたは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> 
4
Philᵀᴹ

私は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;
2
Jonathan Fite