Open1

【LeetCode】SQL Day 2 Select & Order

yzzzyzzz

1873. Calculate Special Bonus

最初where句に条件を入れて絞る方法しか思いつかなかったけどそういえばselect句で場合分けできたな〜と思い出して以下の回答。

select employee_id,
case 
    when employee_id % 2 = 1 
            and  name not like "M%"
        then
            salary
        else 0
    end as bonus
from Employees
order by employee_id

他の回答

条件が少なければif文で書いたほうがスッキリしていて良さそう。
他には%の代わりにmod関数を使ってるのもあった。
ifとcaseの使い分けはどうすればいいんだろうか。

select employee_id, 
if(employee_id%2!=0 and name not like 'M%', salary, 0)
as bonus
from Employees
Order by employee_id;

ついでに新しい知識を手に入れた。
テーブル構造がぐちゃぐちゃの時に効果を発揮しそう。
https://style.potepan.com/articles/23548.html

例えば、カラム名を指定する箇所をcase式で置き換えることで、条件対象カラムを切り替えることが可能です。

627. Swap Salary

上記の問題の後だったのでupdateでもif文で場合わけできそうだなと思って調べてみたらできた。
バッチで全レコード書き換えないといけない時とかは便利そう。
2値での入れ替えだったからif文にしたけど、4個以上くらいであればcase文にしたほうが視認性が良さそう。

update Salary 
set sex = if(sex = "m","f","m") 

他の回答

if文かcase文を使ったものがほとんどだった。

196. Delete Duplicate Emails

これはガチ難問すぎて答えをググってしまった。。
https://www.youtube.com/watch?v=V0-33jrJgwo

自分の回答1

select文を使ってはいけないと言われてもこれしか思いつかなかった。

delete p
from Person p
left join 
(select min(id) id,email
 from Person 
 group by email) as p2 on p.id = p2.id
where p2.id is null

同じテーブルをjoinするんだろうなとは思ったものの、
emailでジョインしたところでそれが何に使えるのかイメージがつかなかった。
idの大小を比較するとは。。。

答え

delete p
from Person p
inner join Person p2 
on p.email = p2.email
and p.id > p2.id

若干イメージがつかなかったのでテスト。
たとえば以下のテーブルがあったとき、下三つのセレクト文は同じ結果が得られる。

  • NULLを許容してjoinするかどうか
  • join前に絞るかどうか
    の2点がポイントかも。
CustomerId Country
1 Brazil
2 Germany
3 Canada
4 Norway
5 Czech Republic
6 Czech Republic
7 Austria
8 Belgium
9 Denmark
10 Brazil
(以降も同じようなデータが続く)
select c1.CustomerId , c1.Country, c2.CustomerId , c2.Country 
from Customer c1
left join Customer c2 on c1.Country = c2.Country
and c1.CustomerId  > c2.CustomerId ;
select c1.CustomerId , c1.Country, c2.CustomerId , c2.Country 
from Customer c1
left join Customer c2 on c1.Country = c2.Country
where c1.CustomerId  > c2.CustomerId ;
select c1.CustomerId , c1.Country, c2.CustomerId , c2.Country 
from Customer c1
inner join Customer c2 on c1.Country = c2.Country
and c1.CustomerId  > c2.CustomerId ;
select c1.CustomerId , c1.Country, c2.CustomerId , c2.Country 
from Customer c1
inner join Customer c2 on c1.Country = c2.Country
where c1.CustomerId  > c2.CustomerId ;