Open1
【LeetCode】SQL Day 2 Select & Order
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;
ついでに新しい知識を手に入れた。
テーブル構造がぐちゃぐちゃの時に効果を発揮しそう。
例えば、カラム名を指定する箇所を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
これはガチ難問すぎて答えをググってしまった。。
自分の回答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 ;