SQL 練習 ドリル 研修コースに参加してみた

今回参加したコースは SQL 練習 ドリル です。
前年 2020 年に実施した SE カレッジの受講者向けアンケートで、受講したいテーマ 第 2 位になったのが SQL です。プログラミング言語のようにいろいろな言語がある訳ではなく共通していて、かつアプリケーションには、ほぼ必須なので、根強いニーズになっているのかも知れません。
さて、このコースはドリル形式です。
ドリルといえば、演習を繰り返して習熟させるものですが、自身の習熟度(レベル)を測るものでもあります。
腕試しに受講してみると…… まったくスキルが足りてないことがわかりました!! いや厳しい。完全に小僧扱いのレベルでした。。出直します!
新人研修や業務で「 SQL 完全に理解した」という方にも、研修や本で勉強したところという方にも、今の SQL スキルがわかり、また 1 日トータルで 30 問以上を演習するほど SQL 漬けで、慣れるのがとても進みます。オススメです!!
では、どんな内容だったのかレポートします!
もくじ
コース情報
想定している受講者 |
|
---|---|
受講目標 |
|
講師紹介
今回登壇されたのは 代田 (しろた) 佳子さん です。
この参加してみたレポートでは 2 度目の登場です。 Oracle Master 教科書の執筆や Oracle University から何度も表彰されている、データベースではスペシャルな講師です。
その執筆歴と表彰歴は伊達ではなく、ドリルの問題も徐々に難易度を上げながら、また、よく迷ってしまうところが出題ポイントになっていました。
それだけでなく問題の解説では、気づきにくいパフォーマンスの注意点や、 SQL と言っても標準の SQL 1999 構文と製品ごとの方言との違いを説明されるなど、データベースのことなら何でも聞ける安心感がありました。
SQL の種類
代田さんから、今回はドリルを中心とした反転授業 (*) の形式で進めるため、もし個別に質問したい場合はブレイクアウトルームに入るよう、説明されました。
その上で、まずは今日扱う SQL の範囲を、 SQL の種類とともに紹介いただきました。
- 定義するのが DDL( Data Definition Language )
- 操作するのが DML( Data Manipulation Language )
- 権限管理するのが DCL( Data Control Language )
今回のコースは DML の中でも SELECT を対象としたものです。
演習環境
今回利用するテーブルと実行環境は以下のとおりです。


Oracle ( Azure 上の Windows に構築)
もしくは
Oracle Live SQL (ブラウザで実行できる Oracle [アカウント登録が必要])
クラウド版があるとは便利です。もし読者の方で試したい方はこちらがオススメです。
予め用意いただいたスキーマやテーブル作成の SQL を実行して演習がスタートです。
SELECT の基本
ここから怒涛の 32 問の演習を行ったのですが、このレポートではその中から(私が門前払われた問題を中心に)ピックアップしました。
全問挑戦したい方は、ぜひコースにご参加ください!
ちなみに演習中はググっても OK で、制限時間は 1 問あたり 5 分 ~ 10 分です。
問2
計算をどのようにしますか?
code解答と解説expand_more
SELECT empno, ename, job, salary+comm FROM emp WHERE deptno=30;
-
解説
- + で計算ができます
- sqlary+comm を別の列名にするときは、横にその別名を書く
SELECT empno, ename, job, salary+comm annsal FROM emp WHERE deptno=30;
問5
「範囲外」の書き方をどうしますか?
code解答と解説expand_more
SELECT deptno,ename,job,salary FROM emp WHERE salary NOT BETWEEN 300000 AND 400000;
SELECT deptno,ename,job,salary FROM emp WHERE salary < 300000 OR salary > 400000;
SELECT deptno,ename,job,salary FROM emp WHERE NOT (salary >= 300000 AND salary <= 400000);
-
解説
- OR に書き換えるのは考えるのが難しい
- NOT ( 条件1 AND 条件2) の () を外すとどうなるでしょう?
- NOT の方が強いので、 AND は条件から外れます
問8
文字列のパターンをどう抽出しますか?
code解答と解説expand_more
SELECT empno,ename FROM emp WHERE ename LIKE '%木 %';
-
解説ポイント
- LIKE を使う
- 文字列のパターンを示すには
% %
でくくる- 1 文字を示すのが
_
- 1 文字を示すのが
- 頭の文字がわからない状態で LIKE を使うとパフォーマンスが落ちる
問11
NULL はどのように解釈されますか?
code解答と解説expand_more
SELECT empno,ename,deptno FROM emp ORDER BY deptno NULLS FIRST;
SELECT empno,ename,job,salary+comm FROM emp ORDER BY salary+comm;
SELECT empno,ename,job,salary+comm FROM emp ORDER BY 4;
SELECT empno,ename,job,NVL(salary,0)+NVL(comm,0) annsal FROM emp ORDER BY annsal;
-
解説
- NULL は最大値の扱いになってしまう( Oracle 、 PostgreSQL の場合)
- NULLS FIRST を使う
- 値に変えてしまう、というやり方もある
- NVL(カラム, 値)
集計関数
問12
どのように集計しますか?
code解答と解説expand_more
SELECT COUNT(*),SUM(salary),AVG(salary),MAX(salary),MIN(salary) FROM emp;
-
解説
- 集計関数
- 人数 COUNT()
- カラム名だけでなく
*
ですべて指定することもできる *
で指定すると NULL もカウントされる- カラム名で指定すると NULL はカウントしない
- カラム名だけでなく
- 合計 SUM()
- 平均 AVG()
- 最大値 MAX()
- 最小値 MIN()
- 人数 COUNT()
問13
- テーブル全体ではなく、値で集計するにはどうしますか?
- NULL の扱いにも注意しましょう
code解答と解説expand_more
SELECT deptno,COUNT(*),COUNT(comm),COUNT(DISTINCT job) FROM emp GROUP BY deptno;
-
解説
- GROUP BY を使います
- GROUP BY で指定した列名以外を SELECT には指定できない
- SELECT に入れたい列名があれば、 GROUP BY にも入れる
- ただし挙動は RDBMS によって変わる
- 種類数
- まず DISTINCT で種類を求める
- その上で COUNT()
副問合せ サブクエリ
問17
- 特殊な副問合せ
- 複数レコードが返ってくる場合はどのようにしますか?
- EXISTS の書き方を調べましょう
code解答と解説expand_more
SELECT deptno,dname FROM dept d
WHERE EXISTS (SELECT 1 FROM emp e WHERE e.deptno=d.deptno);
/* IN を使う場合 */
SELECT deptno,dname FROM dept WHERE deptno IN (SELECT deptno FROM emp);
-
解説
- WHERE は IN を使って複数レコードが返ってきても良いようにする
- ただ何回も同じことを比較してしまうので、この問題ではパフォーマンスが悪い
- EXISTS を使う
- 存在チェックを行う
- 1 つでも値があれば、以降はチェックしない
- (SELECT 1 FROM emp e WHERE e.deptno=d.deptno) の 1 は何でも良い
- 演算子で >, <, >=, <= を使うときはどうするか
- ANY か ALL を使う
- ALL すべての値と比較
- ANY いずれかの値と比較
SELECT deptno,dname FROM dept WHERE deptno > ANY (SELECT deptno FROM emp);
- ANY か ALL を使う
問19
2 つのカラムを受け取る場合の条件の書き方はどのようにしますか?
code解答と解説expand_more
SELECT empno,ename,salary,deptno,mgrno
FROM emp WHERE (deptno,mgrno) IN (SELECT deptno,mgrno
FROM emp WHERE salary = (SELECT MIN(salary) FROM emp));
-
解説
- 分解して考えましょう
- 最も給与が少ない従業員
- 従業員の部門番号(deptno)と直属の上司(mgrno)
- カラムが 2 つに返ってくる場合は WHERE (カラム1, カラム2)
結合
問22
- 結合して集計するにはどうしますか?
- (ヒント) FROM でも副問合せが書ける
- “インライン” で調べてみるとよいでしょう
code解答と解説expand_more
/* oracle */
SELECT d.deptno,d.dname,COUNT(*),SUM(salary)
FROM dept d,emp e WHERE d.deptno = e.deptno GROUP BY d.deptno,d.dname;
/* FROM に副問合せを使う */
SELECT d.deptno,d.dname,e.cntEmp,e.sumSal
FROM dept d,(SELECT deptno,COUNT(*) cntEmp,SUM(salary) sumSal
FROM emp GROUP BY deptno) e WHERE d.deptno = e.deptno;
/* 普通の JOIN */
SELECT d.deptno,d.dname,COUNT(*),SUM(salary)
FROM dept d JOIN emp e ON d.deptno = e.deptno
GROUP BY d.deptno,d.dname;
-
解説
- FROM を使った副問合せは JOIN よりパフォーマンスが良い可能性がある
- JOIN はテーブルごと結合するが、 WHERE などでレコードが少なくなっている
問23
範囲で結合する場合はどうしますか?
code解答と解説expand_more
SELECT e.ename,e.salary,g.grade
FROM emp e, salgrade g WHERE e.salary
BETWEEN g.lowsal AND g.hisal ORDER BY salary DESC;
SELECT e.ename,e.salary,g.grade
FROM emp e JOIN salgrade g ON e.salary
BETWEEN g.lowsal AND g.hisal ORDER BY salary DESC;
-
解説
- 別テーブルの値を BETWEEN に入れて WHERE で比較すればできる
- なお NATURAL JOIN や USING は等価結合なので使えない
問24
結合できる値がないが結合する場合はどうしますか?
code解答と解説expand_more
/* Oracle */
SELECT d.deptno,d.dname,e.empno,e.ename
FROM dept d,emp e WHERE d.deptno(+) = e.deptno;
/* SQL 1999 構文*/
SELECT d.deptno,d.dname,e.empno,e.ename
FROM emp e LEFT OUTER JOIN dept d ON e.deptno = d.deptno;
SELECT d.deptno,d.dname,e.empno,e.ename
FROM dept d RIGHT OUTER JOIN emp e ON d.deptno = e.deptno;
-
解説
- 外部結合を使う
- Oracle では (+) を使う
- SQL 1999 構文では OUTER JOIN を使う
- LEFT では OUTER より左側の FROM のテーブルを使う
- RIGHT では OUTER より右側の JOIN のテーブルを使う
知っておくと便利な SQL
代田さんから、ここまでは必須知識で、ここから先は知っておくと便利なものと紹介いただきました。
問27
集合演算子とはどのようなものでしょうか?
code解答と解説expand_more
SELECT deptno FROM dept MINUS SELECT deptno FROM emp;
-
解説
- 集合演算子は 3 つ
- UNION くっつけてすべて返す
- INTERSECT 同じ部分だけを返す
- MINUS 重なった部分だけをひく
- NOT IN でも書けるが長くなる
レポートではかなり問題を端折っているので、ステップ・バイ・ステップになっていませんが、実際には 基本 → 応用 → さらに応用 と出題されていました。
まとめ
SQL で段階を踏みながら、さまざまな問題に挑戦しました。
読者の皆さんはいかがでしょうか?
ちなみに「ググれば楽勝でしょ」と思っていると、途中からだんだん、どういうアプローチで SQL を組み立てるとよいか難しくなり、時間がまったく足りませんでした。そのうえで解説を聞くと、なるほど、そういう考え方をすればいいのかと納得しました。
悔しくも楽しい時間で、そして、とっても疲れました!
腕試ししたいという方、研修などで SQL だいたい書けるようになってきたという方には、とってもオススメです!
label SEカレッジを詳しく知りたいという方はこちらから !!

IT専門の定額制研修 月額28,000円 ~/ 1社 で IT研修 制度を導入できます。
年間 670 コースをほぼ毎日開催中!!

SEプラスにしかないコンテンツや、研修サービスの運営情報を発信しています。