0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【技術書まとめ】『SQL 第2版 ゼロからはじめるデータベース操作』を読んだまとめ

Last updated at Posted at 2020-05-19

データベース操作を基礎からしっかりと身に付けたいと思ったので手に取った書籍です。

対象

データベース初心者や非エンジニア。

第0章 イントロダクション

書籍では windows 用の設定だけだったので mac 用にqiita記事を参考にしました。
https://qiita.com/ipepi/items/58dedbc0434fa9ea3b71

第1章 データベースとSQL

  • データベースとはそもそも何のために使われるのか
    • 表計算ソフトとどう違うのか
  • 種類と具体例
  • SQLとは何か

実際にSQLを書いてみる

  • create database
  • create table
  • drop table
  • alter table

練習問題でサクッとdrop tableさせるところが面白いなと思いました。練習問題ながら、サクッとテーブルを削除するとどうなるのか身をもって辛さを体験できます。

第2章 検索の基本

  • select
    • asでわかりやすい名前で出力する
    • fromなしで出力することもできる
      • 中身が何でもいいとき
  • '商品' as mojiretsuで定数を出力する
  • select distinctで重複を省く
  • whereで絞り込む
    • 必ずfromの直後に書く
  • --/* */でコメントを書く
  • select文中で計算もできる
    • NULLが入るときに気をつける
  • 文字列型の順序の原則は辞書式
    • 数値の大小とは違う
  • NULLを判別するにはis nullis not nullを使う
  • andor
    • ベン図は便利
    • orよりandの方が優先される
      • ()で調整する
    • NULL不明(UNKNOWN)となる
      • SQLだけは3値論理となる
        • NOT NULL制約で対策

第3章 集約と並べ替え

  • 集約関数とは

    • count
      • 列名を引数にするとNULLを除外した数になる
        • count関数だけの特徴
    • sum
    • avg
    • maxmin
      • どんなデータ型の列にも適用できる
  • 集約関数は最初にNULLを除外する

    • countだけは例外
  • 重複値を除きたいときはdistinct

    • ()の中に書く
    • select count(distinct shohin_bunrui) from shohin;
    • 集計関数ならどれにでも使える
  • group by

    • ケーキのように切り分ける
      • 商品分類ごとなど
    • 必ずfromの後ろにおく
    • NULLは1つのグループとなる
    • whereも一緒に使える
      • whereで先に絞られたレコードから集約される
  • よくある間違い

    1. selectに集約キー以外の列名を書く
      • 1行でグループ化したなら結果も1行になる
      • 書けるもの
        • 定数
        • 集約関数
        • group byで指定した列名
    2. group byしてるときにasを使う
      • SQL内部ではgroup byselectより先になる
        • 別名を知らない
    3. group byはソートしてくれる?
      • してくれない
    4. wherecountなどを書く
      • 集約関数が書けるのはselecthavingorder byだけ
  • having

    • group byでグループ分けし、さらに条件を指定して絞りこむ
    • group byの後ろに書く
    • 一度集約が終わった段階のテーブルを出発点にしている
    • 行に対する条件はwhereで書いた方がいい
      • where shohin_bunrui = '衣服'
      • whereで絞り込んでからソートした方が速い
      • whereはインデックスが使える
  • order by

    • selectの最後に書く
    • 同順位のデータの並び順を決定するには
      • 複数のソートキーを指定する
    • NULLはまとめられる
    • asを使える
      • order byselectより後で実行されるから
    • 列番号は使ってはいけない

第4章 データの更新

  • insert
    • default値は明示的な方が良い
  • insert …… selectでデータをコピーできる
    • バックアップに使える
    • insert内のselectではどんなSQL文でも使える
  • drop table
  • delete
    • delete from shohin;
    • 使えるのはwhereだけ
  • update
    • 列をNULLで更新する
      • NULLクリア
    • 複数更新はset列を増やす
  • transaction
    • ワンセットで行われるべき更新の集合
    • SQL ServerPostgreSQLでは
      • begin transaction
    • MySQLでは
      • start transaction
    • OracleDB2では
      • ない
        • 接続時点でトランザクションが始まっているから
  • commit
    • ファイルでいうところの上書き保存
  • rollback
    • 保存せずに終了
  • ACID特性
    • 原子性(Atomicity)
      • オール・オア・ナッシング
        • commitされるかrollbackされるかどちらかしかない
    • 一貫性(Consistency)
      • 制約違反はエラーになってロールバックされる
        • NOT NULL制約
      • 整合性
    • 独立性(Isolation)
      • トランザクション同士は独立している
    • 永続性(Durability)
      • 復旧手段がある
        • 実行ログ

第5章 複雑な問い合わせ

  • ビュー
    • 実際のデータを保存していないテーブル
      • 保存領域の容量節約できる
      • 使い回しが効く
    • よく使うselectをビューにして使いまわす
  • create view
    • asを省略しない
    • order byは使わない
  • サブクエリ
    • 使い捨てのビュー
      • ビュー定義のselectfromに持ち込んだもの
  • スカラ・サブクエリ
    • 必ず1行1列だけの戻り値を返すサブクエリ
    • 単一の値が書ける所にはどこでも書ける
      • 集約関数をwhereに書けないため重宝する
    • 絶対にサブクエリが複数行を返さないようにする
SELECT shohin_id, shohin_mei, hanbai_tanka
  FROM Shohin
 WHERE hanbai_tanka > (SELECT AVG(hanbai_tanka)
                         FROM Shohin);
  • 相関サブクエリ
    • 小分けにしたグループ内で比較する
    • whereで使う戻り値が複数
      • 対応する列ごとに比較したいときに使う
    • 縛る制限すると呼ばれる
      • 「商品分類で縛って」
    • 結合条件は必ずサブクエリの中に書く
      • 相関名のスコープ
        • S2は消える
--SQL Server、DB2、PostgreSQL、MySQL
SELECT shohin_bunrui, shohin_mei, hanbai_tanka
  FROM Shohin AS S1
 WHERE hanbai_tanka > (SELECT AVG(hanbai_tanka)
                         FROM Shohin AS S2
                        WHERE S1.shohin_bunrui = S2.shohin_bunrui
                        GROUP BY shohin_bunrui);

第6章 関数、述語、CASE文

算術関数

  • abs
    • 絶対値
  • mod
    • 剰余
    • SQL SERVER では使えない
  • round
    • 四捨五入

文字列関数

  • ||
    • 連結
    • SQL Server と MySQL では使えない
    • MySQ は concatを使う
  • length
    • 文字列長
    • SQL Server では使えない
    • DBMS によっては1文字を長さ2以上と数えるLENGTH関数もある
  • lower
    • 小文字化
  • replace
    • 置き換え
  • substring
    • 文字列の切り出し
    • 利用できるのは PostgreSQL と MySQL だけ
  • upper
    • 大文字化

日付関数

  • current_date
    • 実行した日付が出力される
  • current_time
  • current_timestamp
    • 主要DBMS全てで使える
  • extract
    • 日付要素の抜き出し

変数関数

  • cast
    • 型変換
  • coalesce
    • NULLを変換して使いたいときに使用する
SELECT COALESCE(TS.tenpo_id, '不明')  AS tenpo_id, 
       COALESCE(TS.tenpo_mei, '不明') AS tenpo_mei,
       S.shohin_id, 
       S.shohin_mei, 
       S.hanbai_tanka
  FROM TenpoShohin TS RIGHT OUTER JOIN Shohin S
    ON TS.shohin_id = S.shohin_id
ORDER BY tenpo_id;

述語

  • like
    • 部分一致
  • between
    • 範囲検索
  • is nullis not null
  • innot in
    • inの引数にはサブクエリが使える
    • inの中にnullを入れると常に空っぽになってしまう
      • 戻り値にもnullが含まれないように気をつける
--「大阪店に置いてある商品の販売単価」を求める
SELECT shohin_mei, hanbai_tanka
  FROM Shohin
 WHERE shohin_id IN (SELECT shohin_id 
                       FROM TenpoShohin
                      WHERE tenpo_id = '000C');
  • exists
    • ある条件に合致するレコードがあるかどうか
      • truefalse
    • 引数は常にサブクエリ
      • select *と書く
        • 合致するかどうかだけなので列名は気にしない
--EXISTSで「大阪店に置いてある商品の販売単価」を求める
SELECT shohin_mei, hanbai_tanka
  FROM Shohin AS S
 WHERE EXISTS (SELECT *
                 FROM TenpoShohin AS TS
                WHERE TS.tenpo_id = '000C'
                  AND TS.shohin_id = S.shohin_id);

case

  • case
    • elseは省略しない
    • 式を書ける場所ならどこでも書ける
      • selectを柔軟に組み替えられる
--商品分類ごとに販売単価を合計した結果を行列変換する
SELECT SUM(CASE WHEN shohin_bunrui = '衣服'         THEN hanbai_tanka ELSE 0 END) AS sum_tanka_ihuku,
       SUM(CASE WHEN shohin_bunrui = 'キッチン用品' THEN hanbai_tanka ELSE 0 END) AS sum_tanka_kitchen,
       SUM(CASE WHEN shohin_bunrui = '事務用品'     THEN hanbai_tanka ELSE 0 END) AS sum_tanka_jimu
  FROM Shohin;

第7章 集合演算

  • 集合演算の注意事項
    1. 演算対象のレコードの列数は同じであること
    2. 足し算の対象となるレコードの列のデータ型が一致していること
    3. selectはどんなものを指定してもいい。だがorder byは最後に1つだけ

テーブルの足し算と引き算

  • union
    • 和集合
  • union all
    • 重複行を排除しない
  • intersect
    • 共通するレコードを選択する
  • except
    • 引いた残りが選択される
    • どちらから引くかで結果が異なる

結合

  • 結合とは
    • 別テーブルから列を持ってきて増やす
      • whereなどで絞り込むこともできる
  • inner join
    1. fromに複数のテーブルを書く
    2. onの後に結合キーを指定する
    3. selectではTS.tenpo_idなどのように書く
--SQL Server、DB2、PostgreSQL、MySQL
SELECT TS.tenpo_id, TS.tenpo_mei, TS.shohin_id, S.shohin_mei, S.hanbai_tanka
  FROM TenpoShohin AS TS INNER JOIN Shohin AS S
    ON TS.shohin_id = S.shohin_id
ORDER BY tenpo_id;
  • outer join
    1. 片方のテーブルの情報がすべて出力される
      • 行数固定の定型帳票を作る場合に使われる
    2. どちらのテーブルをマスタにするか
      • leftrightで決める
SELECT TS.tenpo_id, TS.tenpo_mei, S.shohin_id, S.shohin_mei, S.hanbai_tanka
  FROM TenpoShohin TS RIGHT OUTER JOIN Shohin S
    ON TS.shohin_id = S.shohin_id
ORDER BY tenpo_id;
  • corss join
    • 実務ではまず使われない
    • inner joinouter joinのベースとなる

第8章 SQLで高度な処理を行なう

ウィンドウ関数

OLAP関数とも呼ばれます。例えばrank関数の場合だと、partition byがテーブルを横方向にカットします。この区切られた部分がウィンドウという範囲です。それをorder byが縦方向に順序づけします。

またウィンドウ関数は引数をとらないため()内は常に空っぽです。

  • rank
    • ランキングを算出する
      • 同順位なら後続の順位が飛ぶ
        • 1位、2位、2位、4位……
  • dense_rank
    • 後続順位が飛ばない
      • 1位、2位、2位、3位……
  • row_number
    • 一意な連番づけをする
--Oracle、DB2、SQL Server、PostgreSQL
SELECT shohin_mei, shohin_bunrui, hanbai_tanka,
       RANK () OVER (PARTITION BY shohin_bunrui
                         ORDER BY hanbai_tanka) AS ranking
  FROM Shohin;
  • sumをウィンドウ関数として使って累計を出す
--Oracle、DB2、SQL Server、PostgreSQL
SELECT shohin_id, shohin_mei, hanbai_tanka,
       SUM (hanbai_tanka) OVER (ORDER BY shohin_id) AS current_sum
  FROM Shohin;
  • avgを使って移動平均を出す
--Oracle、DB2、SQL Server、PostgreSQL
SELECT shohin_id, shohin_mei, hanbai_tanka,
       AVG (hanbai_tanka) OVER (ORDER BY shohin_id
                                 ROWS BETWEEN 1 PRECEDING AND 
                                              1 FOLLOWING) AS moving_avg
  FROM Shohin;
  • レコードをきちんとした順序に並べるには最後にorder byを入れる
    • over内のorder byは計算順序を決める役割しかない
--Oracle、DB2、SQL Server、PostgreSQL
SELECT shohin_mei, shohin_bunrui, hanbai_tanka,
       RANK () OVER (ORDER BY hanbai_tanka) AS ranking
  FROM Shohin
 ORDER BY ranking;

GROUPING演算子

  • rollup
    • 合計・小計値もgroup byと一緒に出したい時に使う
    • group by ()group by (shohin_bunrui)を同時に計算している
--Oracle、DB2、SQL Server、PostgreSQL
SELECT shohin_bunrui, SUM(hanbai_tanka) AS sum_tanka
  FROM Shohin
 GROUP BY ROLLUP(shohin_bunrui);
  • grouping
    • 合計部分に文字列を埋め込める
  • cube
    • group by句のキーのすべての組み合わせを表示する
  • grouping sets
    • 条件を個別指定して抜き出す
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?