達人に学ぶSQL徹底指南書
https://www.seshop.com/static/images/product/22009/L.pnghttps://www.seshop.com/static/images/product/8753/L.png
ミック本 書籍 ミック
2012年 達人に学ぶSQL徹底指南書 電子書籍(ミック)|翔泳社の本
2018年 達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ(ミック)|翔泳社の本
/gosyujin-books/0001: 達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ.pdf
SQL:2003準拠
標準SQLを試した環境
SQL Server 14.0.1000.169
SQL Server Management Studio 15.0.18358.0
case式
本書はcase式の解説から始まる
SQL-92で標準SQLに取り込まれたため、実装に依存しない
それぞれのRDBで代用関数があるが、できるだけ標準語で話すようにしたい
単純case式と検索case式に分類される
単純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
性別
男
検索case式
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との比較ができない
case式は真になるwhenが見つかったら残りは評価しない
各分岐の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
メッセージ 245、レベル 16、状態 1、行 4
varchar の値 '男' をデータ型 int に変換できませんでした。
ただし@sex = '2'の場合は正常に完了して0が返ってくる
なんで?
end書き忘れ
table:result
メッセージ 102、レベル 15、状態 1、行 9
'xxx' 付近に不適切な構文があります。
case式のelseは省略できるが暗黙的にelse nullとされる
select句のcase式を豪快にgroup byにコピーしたもの
code:sql
create table #poptbl(
pref_name varchar(10),
population int
);
insert into #poptbl
(pref_name, population)
values
('徳島', 100),
('香川', 200),
('愛媛', 150),
('高知', 200),
('福岡', 300),
('佐賀', 100),
('長崎', 200),
('東京', 400),
('群馬', 50);
select * from #poptbl;
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
from #poptbl
group by
case pref_name
when '徳島' then '四国'
when '香川' then '四国'
when '愛媛' then '四国'
when '高知' then '四国'
when '福岡' then '九州'
when '佐賀' then '九州'
when '長崎' then '九州'
else 'その他'
end;
--drop table #poptbl;
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
from #poptbl
group by district; -- select句で付けた別名districtを指定
が、SQL Serverは参照できない
列名 'sample' が無効です。
code:ㅤ
メッセージ 207、レベル 16、状態 1、行 46
列名 'district' が無効です。
updateにcase式
条件分岐をSELECT句の中で済ませられるのか…
WHERE句で条件分岐させるのは素人のやること。プロはSELECT句で分岐させる
HAVING句で条件分岐させるのは素人のやること。プロはSELECT句で分岐させる
まだこの境地には達せていない
case文ではなくcase式
式だからどこにでも書ける
ウィンドウ関数
意図せぬクロス結合を防ぐためinner joinを使う
重複行
疑似キー
SQL:2003まで定義されなかったため方言が多い
SERIAL
SEQUENCE
IDENTITY
/gosyujin-books/0064: SQLアンチパターン.pdf
IDリクワイアド
/gosyujin-books/0072: 達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ.pdf
3値論理
true, false, unknown
なぜ3値なのか
NULLを持ち込んだから
本当は2種類のNULLが定義されるはずだった
なぜNULLの比較にはISを使わなければいけないのか
NULLとの比較は結果がunknownになってしまうから
NULLの伝搬
NULLは値ではない
IS_NULLで一語と考える
単純case式は x = yの省略形なのでNULL比較はできないので検索case式を使う
P250 13 RDB近現代史
/gosyujin-books/0261: 達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ.pdf#61d284b82c53d80000d50796
スプレッドシートなどのように二次元的
異なるところもある
データの位置を排除
ループをなくす
E.F.Codd
ループ処理や配列操作などで発生しやすい不具合
原理的に発生しない設計を目指した
ポインタの概念をなくす(ユーザーから隠す)
敢えてそう作った
データ独立の目標
P279 17 順序をめぐる冒険
/gosyujin-books/0290: 達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ.pdf
NULLの扱い
なぜRDBの中にNULLがあると困るのか
/gosyujin-books/0243: 達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ.pdf#61d284b82c53d80000d50718
1つの列に複数の意味を持たせてはいけない
SQLアンチパターンにも同じ説明がある
5章 EAV(エンティティ・アトリビュート・バリュー)
単一参照テーブル
/gosyujin-books/0247: 達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ.pdf#61d284b82c53d80000d50734
コメントはある方がいい
「コードに語らせること」が難しい
段階的にデバッグするのが難しい
コメントは--と/* */がある
個人的には/* */を使いたい
動的管理ビューとかから実行クエリをコピーしてくると一行になってしまう?
こういうクエリが一行で取得されると
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;
インデント
本書ではリバーを意識する
前カンマ、後カンマ
/gosyujin-books/0257: 達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ.pdf#61d284b82c53d80000d50734
クエリを書く順番
SQLはFROM句から書け