達人に学ぶSQL徹底指南書
https://www.seshop.com/static/images/product/22009/L.pnghttps://www.seshop.com/static/images/product/8753/L.png
本書はcase式の解説から始まる
code:sql
declare @sex nvarchar(1);
set @sex = '1';
select
case @sex d
when '1' then '男'
when '2' then '女'
else 'その他'
end as 性別;
table:result
性別
男
code:sql
declare @sex nvarchar(1);
set @sex = '1';
select
case when @sex = '1' then '男'
when @sex = '2' then '女'
else 'その他'
end as 性別;
table:result
性別
男
結果は同じ
違いがわかるだろうか
単純case式の方が読みやすい
単純case式で書ける事は検索case式でも書ける
caseは=で比較しているので、単純case式ではNULLとの比較ができない
各分岐のthenで返ってくるデータ型を揃えなければならない
code:sql
declare @sex nvarchar(1);
set @sex = '1';
select
case @sex
when '1' then '男' /* こっちはvarchar */
when '2' then 0 /* こっちはint */
else 'その他'
end as 性別;
table:result
varchar の値 '男' をデータ型 int に変換できませんでした。
ただし@sex = '2'の場合は正常に完了して0が返ってくる
なんで?
end書き忘れ
table:result
'xxx' 付近に不適切な構文があります。
select句のcase式を豪快にgroup byにコピーしたもの
code:sql
pref_name varchar(10),
population int
);
(pref_name, population)
values
('徳島', 100),
('香川', 200),
('愛媛', 150),
('高知', 200),
('福岡', 300),
('佐賀', 100),
('長崎', 200),
('東京', 400),
('群馬', 50);
select
case pref_name
when '徳島' then '四国'
when '香川' then '四国'
when '愛媛' then '四国'
when '高知' then '四国'
when '福岡' then '九州'
when '佐賀' then '九州'
when '長崎' then '九州'
else 'その他'
end as district,
sum(population) as sum_population
group by
case pref_name
when '徳島' then '四国'
when '香川' then '四国'
when '愛媛' then '四国'
when '高知' then '四国'
when '福岡' then '九州'
when '佐賀' then '九州'
when '長崎' then '九州'
else 'その他'
end;
table:ㅤ
pref_name population
徳島 100
香川 200
愛媛 150
高知 200
福岡 300
佐賀 100
長崎 200
東京 400
群馬 50
table:ㅤ
district sum_population
その他 450
九州 600
四国 650
こう書けるDBMSもある
code:sql
select
case pref_name
when '徳島' then '四国'
when '香川' then '四国'
when '愛媛' then '四国'
when '高知' then '四国'
when '福岡' then '九州'
when '佐賀' then '九州'
when '長崎' then '九州'
else 'その他'
end as district,
sum(population) as sum_population
group by district; -- select句で付けた別名districtを指定
が、SQL Serverは参照できない
code:ㅤ
メッセージ 207、レベル 16、状態 1、行 46
列名 'district' が無効です。
updateにcase式
条件分岐をSELECT句の中で済ませられるのか…
まだこの境地には達せていない
case文ではなくcase式
式だからどこにでも書ける
重複行
疑似キー
SERIAL
SEQUENCE
IDENTITY
true, false, unknown
なぜ3値なのか
NULLを持ち込んだから
なぜNULLの比較にはISを使わなければいけないのか
NULLとの比較は結果がunknownになってしまうから
単純case式は x = yの省略形なのでNULL比較はできないので検索case式を使う
P250 13 RDB近現代史
スプレッドシートなどのように二次元的
異なるところもある
データの位置を排除
ループをなくす
ループ処理や配列操作などで発生しやすい不具合
原理的に発生しない設計を目指した
ポインタの概念をなくす(ユーザーから隠す)
敢えてそう作った
P279 17 順序をめぐる冒険
NULLの扱い
1つの列に複数の意味を持たせてはいけない
コメントはある方がいい
「コードに語らせること」が難しい
段階的にデバッグするのが難しい
コメントは--と/* */がある
個人的には/* */を使いたい
動的管理ビューとかから実行クエリをコピーしてくると一行になってしまう? こういうクエリが一行で取得されると
code:sql
select *
from users
where
id > 10
-- 念のため20才より大きい人
and age > 20
order by
id asc;
こうなってしまうことがある(条件が変わる)
code:sql
select * from users where id > 10 -- 念のため20才より大きい人 and age > 20 order by id asc;
インデント
クエリを書く順番