網頁

2018/12/17

LeetCode Swap Salary 薪水交換

本篇為LeetCode上演算法的簡單問題,Swap Salary

題目如下:

Given a table salary, such as the one below, that has m=male and f=female values. Swap all f and m values (i.e., change all f values to m and vice versa) with a single update query and no intermediate temp table.

For example:

| id | name | sex | salary |
|----|------|-----|--------|
| 1  | A    | m   | 2500   |
| 2  | B    | f   | 1500   |
| 3  | C    | m   | 5500   |
| 4  | D    | f   | 500    |

After running your query, the above salary table should have the following rows:

| id | name | sex | salary |
|----|------|-----|--------|
| 1  | A    | f   | 2500   |
| 2  | B    | m   | 1500   |
| 3  | C    | f   | 5500   |
| 4  | D    | m   | 500    |

這題的題目應改為Swap Sex交換性別才對。

題目就要你將資料表中每一列性別(SEX)的值互換,也就是原本是'm'的改為'f',原本是'f'的改為'm',並且只能使用一句UPDATE敘述完成,不可使用暫存資料表。

因為我對SQL語法或函式很不熟練,所以下面都是參考別人的解法。

MySQL

-- 解法1
UPDATE salary 
SET sex = CASE sex 
          WHEN 'm' THEN 'f' 
          WHEN 'f' THEN 'm' 
          END;

          
-- 解法2
UPDATE salary SET sex = IF(sex = 'm', 'f', 'm');


-- 解法3
UPDATE salary SET sex = CHAR(ASCII(sex) ^ (ASCII('m') ^ ASCII('f')));

以上皆為MySQL的SQL敘述。比較特別的是解法3,例用XOR位元運算子^來做。


不過在Oracle PL/SQL中沒有XOR位元運算子,也沒有IF()函式,但仍可以利用CASE ... WHEN ... THEN

Oracle PL/SQL


>-- 解法1
UPDATE SALARY 
SET SEX = CASE SEX 
          WHEN 'm' THEN 'f' 
          WHEN 'f' THEN 'm' 
          END;

-- 解法2
UPDATE SALARY 
   SET SEX = CHR(ASCII(SEX) + (ASCII('m') + ASCII('f') - BITAND(ASCII('m'), ASCII('f'))*2) - BITAND(ASCII(SEX), (ASCII('m') + ASCII('f') - BITAND(ASCII('m'), ASCII('f'))*2))*2);

-- (ASCII('m') + ASCII('f') - BITAND(ASCII('m'), ASCII('f'))*2) => 11
UPDATE SALARY 
   SET SEX = CHR( (ASCII(SEX) + 11) - (BITAND(ASCII(SEX), 11)*2) );

看看上面那一大串,所以在Oracle中如要用bitwise XOR計算就寫成Function吧。

總之看到交換兩個變數值的題目,記得先想到用XOR位元運算來處理。


參考:

沒有留言:

張貼留言