私はFEデータベースを克服したい(1/3)

 今回はデータベースに関する記事を投稿いたします。
 ちなみにタイトルのFEはFundamental Information Technology Engineer Examinationの略で、
基本情報処理技術者試験のことです。

私、基本情報処理技術者試験のデータベース問題が苦手です。
あまりに解けないので腹が立ってきました。

そこで、本記事では基本情報処理技術者試験の問題を真っ正面から解きつつ、
クエリの感触をつかむことを目的にします。

「データベースのスペシャリストになるかは今は別として、
基本情報処理技術者試験を合格する必要があるので学習を始めた」といったような方を
対象にしています。

今回も私みたいな駆け出し系に向けた内容です。
もちろん達人のご閲覧も歓迎です。

ちなみに、対策ウェブページに行けば回答も解説もあるんですけど、
まあ、別のアプローチをしているとでも解釈してください。
(対策ウェブページ:https://www.fe-siken.com/)

また、とても長いので3回に分けています。
第2回:
https://machi11038004.hatenablog.com/entry/2020/10/19/182807
第3回:
https://machi11038004.hatenablog.com/entry/2020/10/19/182908

内容は以下の通り。

第一回(本記事)---------------------------------
1.準備運動
2.とりあえず問題を見てみる
3.クエリの基本的な文
 3.1 SELECT 句+FROM句の例
 3.2 SELECT句 + FROM句 + WHERE句の例
 3.3 SELECT句 + FROM句 + GROUP BY句の例
 3.4 SELECT句 + FROM句 + GROUP BY句 + HAVING句の例
 3.5 SELECT句 + FROM句 + ORDER BY句の例
4.アスタリスク(*)
第二回---------------------------------
5.関数、式、述語
6.集合演算、結合
7.その他キーワード
第三回---------------------------------
8.問題に挑む
9.おわりに


それでは早速参ります。

1.準備運動

そもそも データベースって何ですか?という方もいらっしゃるかもしれませんので、
ざっと全体の話をします。

データベースはデータを管理するシステムで、
多くのアプリケーションの必須構成要素です。

いろんな種類がありますが、中でもリレーショナルデータベースという種類がよく使われます。
基本情報処理技術者試験でもディープな回答を求められるのはこの種類です。

リレーショナルデータベースでは、二次元の表でデータを管理します。

・二次元の表の例

 学生番号 |   名前    |   誕生日   |  所属
----------+-----------+------------+--------
     1000 | 山田 太郎 | 2000-01-01 | 3年A組
     1001 | 田中 花子 | 2000-01-02 | 2年B組
     1002 | 齋藤 次郎 | 2000-01-03 | 1年C組
     1003 | 鈴木 仁子 | 2000-01-04 | 2年D組
     1004 | 高橋 三郎 | 2000-01-05 | 3年E組

行のことを「行」や「レコード」と呼びます。
この例でいうと「山田太郎」以下がレコードで、5つのレコードがあります。

列のことを「列」や「カラム」や「フィールド」と呼びます。
この例でいうと列が4つあります。
そしてこの表のことを「テーブル」と呼びます。

実際のリレーショナルデータベースでは複数のテーブルを管理します。

また、複数のレコードから必要なデータを取り出すことを「クエリ」といいます。
クエリとは「問い合わせ」という意味です。
クエリのような操作をする際に使う言語を「SQL」といいます。
Structured Query Languageの略です。

2.とりあえず問題を見てみる

雰囲気をつかむ為に問題の一部をみてみます。令和元年の秋期のものです。

流し見でいいです。
初めに言っておきますが、私含め初学者はほぼ確実にアレルギー出ます笑。
f:id:machi11038004:20201014230543p:plain
まるで暗号です...。

3.クエリの基本的な文

雰囲気がわかったところで、いったん問題は置いておいて、
ここから私なりのクエリの理解について示します。

クエリは、多くの場合で「SELECT文」のことを指します。
必要なデータを意図通りに選んで取得するということです。

SELECT文は、以下の「句」から成り立ちます。

1. SELECT句(出力するときはどの列を残すの?)
2. FROM句(どのテーブルを使うの?)
3. WHERE句(行を抽出する時の条件は?)
4. GROUP BY句(〇〇ごとに分けて出力したいとかある?)
5. HAVING句(〇〇ごとに分けた場合どれを残したい?)
6. ORDER BY句(出力する時、どういう行の順にする?)

全てが必ず必要ではありません。最小でSELECT句だけで動きます。
各句の組み合わせは必要に応じて、ということになります。 
ただし、記述する順番は上の番号順と決まっています。

サンプルを使ってみてみます。
例として、以下のような書籍を管理する「books」テーブルで見ていきます。
(今 私が適当に作ったものです。)

 book_id |         title          | category | price |  release
---------+------------------------+----------+-------+------------
       1 | ドラゴソボール         | 漫画     |   480 | 2000-01-01
       2 | 名探偵ドイル           | 漫画     |   600 | 2000-01-01
       3 | ジュラえもん           | 漫画     |   480 | 2000-03-01
       4 | スタジオギブリアート集 | 芸術     |  3800 | 2000-05-01
       5 | 風景水彩画集           | 芸術     |  2980 | 2000-05-01
       6 | 静物油絵集             | 芸術     |  4800 | 2000-06-01
       7 | 国内絶景写真集         | 写真集   |  5600 | 2000-07-01
       8 | ヨーロッパ写真集       | 写真集   |  3200 | 2000-08-01
       9 | 週刊少年チャンプ       | 雑誌     |   280 | 2000-09-01
      10 | ファッションkankam     | 雑誌     |   980 | 2000-10-01
      11 | 科学雑誌アイザック     | 雑誌     |  1280 | 2000-11-01
      12 | 孤独に学ぶRuby         | 技術書   |  3200 | 2000-12-01
      13 | 孤独に学ぶPython       | 技術書   |  3000 | 2000-12-01
      14 | 孤独に学ぶPHP          | 技術書   |  3500 | 2001-02-01
(14 行)

book_idはid、titleは書籍のタイトル、categoryは書籍のカテゴリ、priceは書籍の値段、
releaseは書籍の発売日です。

3.1 SELECT 句+FROM句の例

「出力するときはどの列を残すの?+どのテーブルを使うの?」です。

SELECT句の後に、列名を書きます。複数あればカンマで区切ります。
実は列名以外も受け付けますが、5節で後述します(次回の記事です)。
FROM句の後は、テーブル名を一つだけ書きます。

・タイトルと値段だけ表示する。
コマンド

SELECT title, price FROM books;

結果

         title          | price
------------------------+-------
 ドラゴソボール         |   480
 名探偵ドイル           |   600
 ジュラえもん           |   480
 スタジオギブリアート集 |  3800
 風景水彩画集           |  2980
 静物油絵集             |  4800
 国内絶景写真集         |  5600
 ヨーロッパ写真集       |  3200
 週刊少年チャンプ       |   280
 ファッションkankam     |   980
 科学雑誌アイザック     |  1280
 孤独に学ぶRuby         |  3200
 孤独に学ぶPython       |  3000
 孤独に学ぶPHP          |  3500
(14 行)


3.2 SELECT句 + FROM句 + WHERE句の例

「出力するときはどの列を残すの?+どのテーブルを使うの?+行を抽出する時の条件は?」です。

WHERE句の後は、列名に対して条件式を書きます。

・価格が1000円以上の書籍のタイトルと値段を表示する
コマンド

SELECT title, price FROM books WHERE price >= 1000;

結果

         title          | price
------------------------+-------
 スタジオギブリアート集 |  3800
 風景水彩画集           |  2980
 静物油絵集             |  4800
 国内絶景写真集         |  5600
 ヨーロッパ写真集       |  3200
 科学雑誌アイザック     |  1280
 孤独に学ぶRuby         |  3200
 孤独に学ぶPython       |  3000
 孤独に学ぶPHP          |  3500
(9 行)

条件式で”等しい”を表現するときは「=」を使います。

・カテゴリが漫画のタイトルと値段とカテゴリーを表示する
コマンド

SELECT title, price, category FROM books WHERE category = '漫画';

結果

     title      | price | category
----------------+-------+----------
 ドラゴソボール |   480 | 漫画
 名探偵ドイル   |   600 | 漫画
 ジュラえもん   |   480 | 漫画
(3 行)

3.3 SELECT句 + FROM句 + GROUP BY句の例

「出力するときはどの列を残すの?+どのテーブルを使うの?
+〇〇ごとに分けて出力したいとかある?」です。

GROUP BY句の後には列名を書きます。

・カテゴリごとに表示する。
コマンド

SELECT category FROM books GROUP BY category;

結果

 category
----------
 漫画
 芸術
 写真集
 技術書
 雑誌
(5 行)


GROUP BY句に続く列名は、カンマで区切って複数指定できます。 
その場合、〇〇ごとに区切ったものをさらに△△ごとに区切るという意味になります。
 
・カテゴリごとに、発売日で分けて表示する。
コマンド

SELECT category, release FROM books GROUP BY category, release;

結果

 category |  release
----------+------------
 雑誌     | 2000-09-01
 雑誌     | 2000-11-01
 技術書   | 2000-12-01
 写真集   | 2000-08-01
 雑誌     | 2000-10-01
 漫画     | 2000-03-01
 漫画     | 2000-01-01
 芸術     | 2000-06-01
 芸術     | 2000-05-01
 写真集   | 2000-07-01
 技術書   | 2001-02-01
(11 行)

3.4 SELECT句 + FROM句 + GROUP BY句 + HAVING句の例

「出力するときはどの列を残すの?+どのテーブルを使うの?
+〇〇ごとに分けて出力したいとかある?+〇〇ごとに分けた場合どれを残したい?」です。

HAVING句はGROUP BY句とセットで使います。
HAVING句の後には、条件式を書きます。
この条件式は、GROUP BY句で区切られたあとのテーブルに対して行われる、
という前提さえ守った内容であればOKです。

・カテゴリごとに、さらに発売日ごとに分けて、かつ漫画だけを表示する
コマンド

SELECT category, release FROM books
GROUP BY category, release HAVING category = '漫画';

結果

 category |  release
----------+------------
 漫画     | 2000-01-01
 漫画     | 2000-03-01
(2 行)

3.5 SELECT句 + FROM句 + ORDER BY句の例

「出力するときはどの列を残すの?+どのテーブルを使うの?
+出力する時、どういう行の順にする?」です。

ORDER BY句の後には、並び替えの基準にする列名を書きます。
データベースではデータの型が決まっていますから、
その型に沿って昇順に表示されます。

・値段が安い順に書籍のタイトルと値段を表示する
コマンド

SELECT title, price FROM books ORDER BY price;

結果

         title          | price
------------------------+-------
 週刊少年チャンプ       |   280
 ジュラえもん           |   480
 ドラゴソボール         |   480
 名探偵ドイル           |   600
 ファッションkankam     |   980
 科学雑誌アイザック     |  1280
 風景水彩画集           |  2980
 孤独に学ぶPython       |  3000
 ヨーロッパ写真集       |  3200
 孤独に学ぶRuby         |  3200
 孤独に学ぶPHP          |  3500
 スタジオギブリアート集 |  3800
 静物油絵集             |  4800
 国内絶景写真集         |  5600
(14 行)


降順表示も可能です。その場合は、ORDER BY 句の列名の後ろに、「DESC」と書きます。

・値段が高い順に書籍のタイトルと値段を表示する
コマンド

SELECT title, price FROM books ORDER BY price DESC;

結果

         title          | price
------------------------+-------
 国内絶景写真集         |  5600
 静物油絵集             |  4800
 スタジオギブリアート集 |  3800
 孤独に学ぶPHP          |  3500
 ヨーロッパ写真集       |  3200
 孤独に学ぶRuby         |  3200
 孤独に学ぶPython       |  3000
 風景水彩画集           |  2980
 科学雑誌アイザック     |  1280
 ファッションkankam     |   980
 名探偵ドイル           |   600
 ジュラえもん           |   480
 ドラゴソボール         |   480
 週刊少年チャンプ       |   280
(14 行)

余談ですが、DESCの部分に「ASC」と書くと、明示的に昇順指定したことになります。

ORDER BY句に続く列名は、カンマで区切って複数指定できます。 
その場合、最初に指定した列に対して並び替えて、さらにその中で並び替えるという意味になります。

・値段順に表示させた上で、さらにid順に表示する
コマンド

SELECT title, price, book_id FROM books ORDER BY price, book_id;

結果

         title          | price | book_id
------------------------+-------+---------
 週刊少年チャンプ       |   280 |       9
 ドラゴソボール         |   480 |       1
 ジュラえもん           |   480 |       3
 名探偵ドイル           |   600 |       2
 ファッションkankam     |   980 |      10
 科学雑誌アイザック     |  1280 |      11
 風景水彩画集           |  2980 |       5
 孤独に学ぶPython       |  3000 |      13
 ヨーロッパ写真集       |  3200 |       8
 孤独に学ぶRuby         |  3200 |      12
 孤独に学ぶPHP          |  3500 |      14
 スタジオギブリアート集 |  3800 |       4
 静物油絵集             |  4800 |       6
 国内絶景写真集         |  5600 |       7
(14 行)

値段が一緒のものは、さらにidの昇順に並んでいます。

4.アスタリスク

「*」をアスタリスクといいます。データベースにおいては「全ての列」という意味です。
ですから、テーブルを表示するときにすべての列を表示させたければ、
SELECTに続けて*を書くだけで済みます。
コマンド

SELECT * FROM books;

結果

 book_id |         title          | category | price |  release
---------+------------------------+----------+-------+------------
       1 | ドラゴソボール         | 漫画     |   480 | 2000-01-01
       2 | 名探偵ドイル           | 漫画     |   600 | 2000-01-01
       3 | ジュラえもん           | 漫画     |   480 | 2000-03-01
       4 | スタジオギブリアート集 | 芸術     |  3800 | 2000-05-01
       5 | 風景水彩画集           | 芸術     |  2980 | 2000-05-01
       6 | 静物油絵集             | 芸術     |  4800 | 2000-06-01
       7 | 国内絶景写真集         | 写真集   |  5600 | 2000-07-01
       8 | ヨーロッパ写真集       | 写真集   |  3200 | 2000-08-01
       9 | 週刊少年チャンプ       | 雑誌     |   280 | 2000-09-01
      10 | ファッションkankam     | 雑誌     |   980 | 2000-10-01
      11 | 科学雑誌アイザック     | 雑誌     |  1280 | 2000-11-01
      12 | 孤独に学ぶRuby         | 技術書   |  3200 | 2000-12-01
      13 | 孤独に学ぶPython       | 技術書   |  3000 | 2000-12-01
      14 | 孤独に学ぶPHP          | 技術書   |  3500 | 2001-02-01
(14 行)

この場合、

SELECT * FROM books;

は、

SELECT book_id, title, category, price, release FROM books;

と同じです。

次回に続きます。
続き:
https://machi11038004.hatenablog.com/entry/2020/10/19/182807


参考文献:
キタミ式イラストIT塾 基本情報技術者 令和02年 (情報処理技術者試験)
SQL 第2版 ゼロからはじめるデータベース操作