はじめに
基本的なデータ操作に関する備忘録です。
細かい構文というより処理の流れを把握できるようにメモしています。
集計とグループ化
集計関数を用いて検索結果(かグループ化した場合はグループ毎)に対して集計を行う。
そのためSELECT文の選択する列名、HAVING句、もしくはORDER BY句のみ記述できる。
処理の流れ
①もとのテーブルに対して検索をかける (where)
②グループ化する (group by)
③グループ毎に集計する (集計関数)
④集計結果に対して絞りこむ (having)
⑤結果表に表示する列を絞りこむ (select)
select 列名,集計関数 -- 4.グループ毎に集計する
-- 6.表示する列を絞りこむ
from テーブル名 -- 1.テーブル指定
where 条件式 -- 2.行を絞って検索する
group by 列名 -- 3.検索結果をグループで分ける
having 条件式 -- 5.集計結果に対して条件で絞りこむ
order by 列名 -- 7.結果表をソートする
副問合せ
選択条件の中に別のselect文による検索結果を指定できる。
処理の流れ
①内側(カッコ内)のselect文が実行される
②外側のselect文が①の結果を受け取り、選択のための条件とする
-- 一意の値が返る
select 品名,単価
from 商品一覧
where 単価 = (select max(単価)
from 商品一覧); -- 単価が最も高い商品とその単価を表示する
update 名簿1
set 氏名 = (select イングリッシュネーム
from 名簿2
where 名簿1.ID = 名簿2.ID); -- 同一IDのデータに対して名簿1の氏名を名簿2のイングリッシュネームで更新する
-- 複数の値が返る
select 品番, 数量
from 在庫
where 品番 in (select 品番
from 商品一覧
where 分類 = '1') -- 分類1のすべての品番の在庫数を表示する
-- 表が返る
select sum(total.数量)
from (select 品番, 数量
from 関東在庫
where 品番 = '1'
union
select 品番, 数量
from 関西在庫
where 品番 = '1') as total; -- 関東と関西の在庫の合計を表示する
insert into 出荷履歴 (日付, 品番, 数量)
select '2024-08-11', 品番, 数量
from 出荷履歴
where 日付 = '2024-08-10'; --翌日データとして前日データをそのままコピーする
相関副問合せ
処理の流れ
①主問合せで1行を取り出す
②①で取り出した1行に対して副問合せで検索が実行される
③主問合せで取り出す行数分①と②を繰り返す
select 品名
from 商品一覧 as S
where not exists (select *
from 在庫 as Z
where S.品番 = Z.品番); -- 在庫テーブルに登録されていない商品名を表示する
結合
結合条件に応じて複数のテーブルをまとめて表示することができる。
処理の流れ
左表(from)に対して、右表(join)の内容を条件に応じて繋げ合わせる。
※3テーブル以上を結合する場合、前から順番に結合される
①左表(from)と右表(最初に出てくるjoin)が結合される
②①の結果を左表として右表(2番目に出てくるjoin)が結合される
内部結合
・結合条件に合致する行が右表に複数ある場合、左表をコピーして結合する
・結合条件に合致する行が右表にない場合、左表の行を削除して結合する
select S.品名, Z.数量
from 商品一覧 as S
inner join 在庫 as Z
on S.品番 = Z.品番 -- 在庫テーブルに登録されていない品番のデータは結果に出力されない
外部結合
・左外部結合(left outer join)では、左表に対して右表に結合相手となるデータがない場合、右表の値をNULLに設定した上で左表の全行を結果として出力する。
・右外部結合は上記の逆で、右表は全行が出力される。
select S.品名, Z.数量
from 商品一覧 as S
left outer join 在庫 as Z
on S.品番 = Z.品番 -- 在庫テーブルに登録されていない品番のデータは数量NULLとなるが、品名はすべて出力される。
おわりに
追記したいことがあれば随時更新します。
また、誤りを見つけられましたら報告いただければ幸いです。