🙆‍♀️

SQL ~ゼロからはじめるデータベース操作~ を読んで【③】

2024/04/13に公開

前回の続き。
https://zenn.dev/db_engineer/articles/ecccff4fa24ae2

第2章 検索の基本

・SELECT文の基本

テーブルから列を出力するためにSELECT文を使用します。

### 指定した列を出力する場合
SELECT <列名1>, <列名2>, <列名3>,...
FROM <テーブル名>;

### 全ての列を出力する場合
SELECT *
FROM <テーブル名>;
### 指定列の出力
shop=# SELECT shohin_id, shohin_mei, shiire_tanka FROM Shohin;
 shohin_id |   shohin_mei   | shiire_tanka
-----------+----------------+--------------
 0001      | Tシャツ        |          500
 0002      | 穴あけパンチ   |          320
 0003      | カッターシャツ |         2800
 0004      | 包丁           |         2800
 0005      | 圧力鍋         |         5000
 0006      | フォーク       |
 0007      | おろしがね     |          790
 0008      | ボールペン     |
(8 rows)

shop=#

### 全列の出力
shop=# SELECT * FROM Shohin;
 shohin_id |   shohin_mei   | shohin_bunrui | hanbai_tanka | shiire_tanka |  torokubi
-----------+----------------+---------------+--------------+--------------+------------
 0001      | Tシャツ        | 衣服          |         1000 |          500 | 2009-09-20
 0002      | 穴あけパンチ   | 事務用品      |          500 |          320 | 2009-09-11
 0003      | カッターシャツ | 衣服          |         4000 |         2800 |
 0004      | 包丁           | キッチン用品  |         3000 |         2800 | 2009-09-20
 0005      | 圧力鍋         | キッチン用品  |         6800 |         5000 | 2009-01-15
 0006      | フォーク       | キッチン用品  |          500 |              | 2009-09-20
 0007      | おろしがね     | キッチン用品  |          880 |          790 | 2008-04-28
 0008      | ボールペン     | 事務用品      |          100 |              | 2009-11-11
(8 rows)

shop=#

列を別名で出力

ASキーワードの利用で列に別名をつけて出力します。
こうすることで、実行結果を見やすくすることができます。
日本語の別名をつける際はダブルクォーテーション(")で囲みます。

SELECT <列名1> AS <別名1>, <列名2> AS "<別名2>",...
FROM <テーブル名>;
shop=# SELECT shohin_id AS id, shohin_mei AS namae, shiire_tanka AS tanka FROM Shohin;
  id  |     namae      | tanka
------+----------------+-------
 0001 | Tシャツ        |   500
 0002 | 穴あけパンチ   |   320
 0003 | カッターシャツ |  2800
 0004 | 包丁           |  2800
 0005 | 圧力鍋         |  5000
 0006 | フォーク       |
 0007 | おろしがね     |   790
 0008 | ボールペン     |
(8 rows)

shop=#

shop=# SELECT shohin_id AS "商品ID", shohin_mei AS "商品名", shiire_tanka AS "仕入単価" FROM Shohin;
 商品ID |     商品名     | 仕入単価
--------+----------------+----------
 0001   | Tシャツ        |      500
 0002   | 穴あけパンチ   |      320
 0003   | カッターシャツ |     2800
 0004   | 包丁           |     2800
 0005   | 圧力鍋         |     5000
 0006   | フォーク       |
 0007   | おろしがね     |      790
 0008   | ボールペン     |
(8 rows)

shop=#

定数で出力

列名ではなく、別途定数を利用して、既存の列名と共にデータを出力できます。

SELECT <データ名1> AS <列名1>, <データ名2> AS "<列名2>",<既存列名1>,<既存列名2>... FROM <テーブル名>;
shop=# SELECT '商品' AS mojiretsu, 38 AS kazu, '2024-03-30' AS hizuke, shohin_id, shohin_mei FROM Shohin;
 mojiretsu | kazu |   hizuke   | shohin_id |   shohin_mei
-----------+------+------------+-----------+----------------
 商品      |   38 | 2024-03-30 | 0001      | Tシャツ
 商品      |   38 | 2024-03-30 | 0002      | 穴あけパンチ
 商品      |   38 | 2024-03-30 | 0003      | カッターシャツ
 商品      |   38 | 2024-03-30 | 0004      | 包丁
 商品      |   38 | 2024-03-30 | 0005      | 圧力鍋
 商品      |   38 | 2024-03-30 | 0006      | フォーク
 商品      |   38 | 2024-03-30 | 0007      | おろしがね
 商品      |   38 | 2024-03-30 | 0008      | ボールペン
(8 rows)

shop=#

重複している行を省いて出力

重複しているデータを省略して出力したい場合はDISTINCTを使用します。

SELECT DISTINCT <列名1>
FROM <テーブル名>;
shop=# SELECT DISTINCT shohin_bunrui FROM Shohin;
 shohin_bunrui
---------------
 キッチン用品
 衣服
 事務用品
(3 rows)

shop=#

重複している分類は削除されています。NULL値についても同様に1つにまとめられます。
列名を複数並べた場合は、全てに当てはまる(かつ)のものだけ省略される。

shop=# SELECT DISTINCT shohin_bunrui, torokubi FROM Shohin;
 shohin_bunrui |  torokubi
---------------+------------
 衣服          |
 キッチン用品  | 2009-01-15
 衣服          | 2009-09-20
 キッチン用品  | 2008-04-28
 事務用品      | 2009-11-11
 事務用品      | 2009-09-11
 キッチン用品  | 2009-09-20
(7 rows)

shop=#

WHERE句で行をフィルタリング

テーブル内で必要な行だけを抽出するためにWHERE句を利用します。

SELECT <列名>, ...
FROM <テーブル名>
WHERE <条件式>;

商品分類が「衣服」のレコードを抽出したい場合は以下のようなSQL文を使用します。
検索条件をSELECTに含めなくても問題ありません。
ただし、SQLのルールでは句の記述順が決まっており、WHERE句はFROM句の直後に書く必要があります。

shop=# SELECT shohin_mei, shohin_bunrui FROM Shohin WHERE shohin_bunrui = '衣服';
   shohin_mei   | shohin_bunrui
----------------+---------------
 Tシャツ         | 衣服
 カッターシャツ   | 衣服
(2 rows)

shop=#

SQL内へのコメント追加方法

SQL文の説明のためにコメントを追加したい場合、1行コメントであれば「--」、複数行であれば「/*
*/」を利用します。

### 1行の場合
shop=# -- このSELECT文は商品分類が「衣類」を抽出します。
shop=# SELECT shohin_mei, shohin_bunrui FROM Shohin WHERE shohin_bunrui = '衣服';
   shohin_mei   | shohin_bunrui
----------------+---------------
 Tシャツ        | 衣服
 カッターシャツ | 衣服
(2 rows)

shop=#

### 複数行の場合
shop=# /*このSELECT文は
shop*# 商品分類が「衣類」を抽出します。*/
shop-# SELECT shohin_mei, shohin_bunrui FROM Shohin WHERE shohin_bunrui = '衣服';
   shohin_mei   | shohin_bunrui
----------------+---------------
 Tシャツ        | 衣服
 カッターシャツ | 衣服
(2 rows)

shop=#

・算術演算子と比較演算子

算術演算子

SQL文内で四則演算を行う際に算術演算子を使用します。

演算子 記号
足し算 +
引き算 -
掛け算 *
割り算 /
shop=# -- 販売単価の4倍の価格を抽出します。
shop=# SELECT shohin_mei, hanbai_tanka, hanbai_tanka * 4 AS "hanbai_tanka_x4" FROM Shohin;
   shohin_mei   | hanbai_tanka | hanbai_tanka_x4
----------------+--------------+-----------------
 Tシャツ        |         1000 |            4000
 穴あけパンチ   |          500 |            2000
 カッターシャツ |         4000 |           16000
 包丁           |         3000 |           12000
 圧力鍋         |         6800 |           27200
 フォーク       |          500 |            2000
 おろしがね     |          880 |            3520
 ボールペン     |          100 |             400
(8 rows)

shop=#

演算の中にNULLを入れると結果はNULLが出力されます。
先ほどの演算に +NULLを追加すると演算結果は空欄になりました。

shop=# SELECT shohin_mei, hanbai_tanka, hanbai_tanka * 4 + NULL AS "hanbai_tanka_x4" FROM Shohin;
   shohin_mei   | hanbai_tanka | hanbai_tanka_x4
----------------+--------------+-----------------
 Tシャツ        |         1000 |
 穴あけパンチ   |          500 |
 カッターシャツ |         4000 |
 包丁           |         3000 |
 圧力鍋         |         6800 |
 フォーク       |          500 |
 おろしがね     |          880 |
 ボールペン     |          100 |
(8 rows)

shop=#

比較演算子

テーブル内で指定条件のレコードを抽出する際に比較演算子を利用します。

演算子 記号
~と等しい =
~と等しくない <>
~以上 >=
~より大きい >
~以下 <=
~より小さい <
shop=# -- 現在登録されているデータを確認
shop=# SELECT * FROM Shohin;
 shohin_id |   shohin_mei   | shohin_bunrui | hanbai_tanka | shiire_tanka |  torokubi
-----------+----------------+---------------+--------------+--------------+------------
 0001      | Tシャツ        | 衣服          |         1000 |          500 | 2009-09-20
 0002      | 穴あけパンチ   | 事務用品      |          500 |          320 | 2009-09-11
 0003      | カッターシャツ | 衣服          |         4000 |         2800 |
 0004      | 包丁           | キッチン用品  |         3000 |         2800 | 2009-09-20
 0005      | 圧力鍋         | キッチン用品  |         6800 |         5000 | 2009-01-15
 0006      | フォーク       | キッチン用品  |          500 |              | 2009-09-20
 0007      | おろしがね     | キッチン用品  |          880 |          790 | 2008-04-28
 0008      | ボールペン     | 事務用品      |          100 |              | 2009-11-11
(8 rows)

shop=#


shop=# -- 商品分類がキッチン用品以外を選択
SELECT * FROM Shohin WHERE shohin_bunrui <> 'キッチン用品';
 shohin_id |   shohin_mei   | shohin_bunrui | hanbai_tanka | shiire_tanka |  torokubi
-----------+----------------+---------------+--------------+--------------+------------
 0001      | Tシャツ        | 衣服          |         1000 |          500 | 2009-09-20
 0002      | 穴あけパンチ   | 事務用品      |          500 |          320 | 2009-09-11
 0003      | カッターシャツ | 衣服          |         4000 |         2800 |
 0008      | ボールペン     | 事務用品      |          100 |              | 2009-11-11
(4 rows)

shop=#


shop=# -- 販売単価が1000円以下を選択
shop=# SELECT * FROM Shohin WHERE hanbai_tanka <= 1000;
 shohin_id |  shohin_mei  | shohin_bunrui | hanbai_tanka | shiire_tanka |  torokubi
-----------+--------------+---------------+--------------+--------------+------------
 0001      | Tシャツ      | 衣服          |         1000 |          500 | 2009-09-20
 0002      | 穴あけパンチ | 事務用品      |          500 |          320 | 2009-09-11
 0006      | フォーク     | キッチン用品  |          500 |              | 2009-09-20
 0007      | おろしがね   | キッチン用品  |          880 |          790 | 2008-04-28
 0008      | ボールペン   | 事務用品      |          100 |              | 2009-11-11
(5 rows)

shop=#

shop=# -- 登録日が2009/9/20以降を選択
shop=#  SELECT * FROM Shohin WHERE torokubi >= '2009-09-20';
 shohin_id | shohin_mei | shohin_bunrui | hanbai_tanka | shiire_tanka |  torokubi
-----------+------------+---------------+--------------+--------------+------------
 0001      | Tシャツ    | 衣服          |         1000 |          500 | 2009-09-20
 0004      | 包丁       | キッチン用品  |         3000 |         2800 | 2009-09-20
 0006      | フォーク   | キッチン用品  |          500 |              | 2009-09-20
 0008      | ボールペン | 事務用品      |          100 |              | 2009-11-11
(4 rows)

shop=#

shop=# -- 販売単価が仕入単価より500円以上安い
shop=# SELECT * FROM Shohin WHERE hanbai_tanka - shiire_tanka <= 500;
 shohin_id |  shohin_mei  | shohin_bunrui | hanbai_tanka | shiire_tanka |  torokubi
-----------+--------------+---------------+--------------+--------------+------------
 0001      | Tシャツ      | 衣服          |         1000 |          500 | 2009-09-20
 0002      | 穴あけパンチ | 事務用品      |          500 |          320 | 2009-09-11
 0004      | 包丁         | キッチン用品  |         3000 |         2800 | 2009-09-20
 0007      | おろしがね   | キッチン用品  |          880 |          790 | 2008-04-28
(4 rows)

shop=#

文字列型への不等号使用

数字のデータ型が数値(INTEGER型)の場合と、文字列(CHAR型、VARCHAR型)の場合では、不等号を使用した出力結果は異なります。
例えば、[1,2,3,4,10,20,21,40,100]の場合、INTEGER型であればこのままの順番で不等号が適用されますが、CHAR型の場合は[1,10,100,2,20,21,3,4,40]となり、大小の順序が異なります。

NULL値への比較演算子使用

NULL値は比較演算子の対象からは除外されるため、NULL値を検索条件とする場合は別の専用の演算子を使用する必要があります。

shop=# -- 仕入単価がNULLのレコードを選択(IS NULL)
shop=# SELECT shohin_mei, shiire_tanka FROM Shohin WHERE shiire_tanka IS NULL;
 shohin_mei | shiire_tanka
------------+--------------
 フォーク   |
 ボールペン |
(2 rows)

shop=#

shop=# -- 仕入単価がNULL以外のレコードを選択(IS NOT NULL)
shop=# SELECT shohin_mei, shiire_tanka FROM Shohin WHERE shiire_tanka IS NOT NULL;
   shohin_mei   | shiire_tanka
----------------+--------------
 Tシャツ        |          500
 穴あけパンチ   |          320
 カッターシャツ |         2800
 包丁           |         2800
 圧力鍋         |         5000
 おろしがね     |          790
(6 rows)

shop=#

shop=# --通常の比較演算子ではNULL値のレコードは出力されない
shop=# SELECT shohin_mei, shiire_tanka FROM Shohin WHERE shiire_tanka <= 1000;
  shohin_mei  | shiire_tanka
--------------+--------------
 Tシャツ      |          500
 穴あけパンチ |          320
 おろしがね   |          790
(3 rows)

shop=#

・論理演算子

複数の検索条件を組み合わせる際に論理演算子を使用します。

演算子 記号
~ではない NOT
または OR
かつ AND
shop=# -- 販売単価が2,000円以上ではない商品を検索(=2,000円以下)【NOT】
shop=# SELECT shohin_mei, hanbai_tanka FROM Shohin WHERE NOT hanbai_tanka >= 2000;
  shohin_mei  | hanbai_tanka
--------------+--------------
 Tシャツ      |         1000
 穴あけパンチ |          500
 フォーク     |          500
 おろしがね   |          880
 ボールペン   |          100
(5 rows)

shop=#

shop=# -- 商品分類がキッチン用品、または販売単価が4,000円以上の商品を検索【OR】
shop=# SELECT shohin_mei, shohin_bunrui, hanbai_tanka FROM Shohin WHERE shohin_bunrui = 'キッチン用品' OR hanbai_tanka >= 4000;
   shohin_mei   | shohin_bunrui | hanbai_tanka
----------------+---------------+--------------
 カッターシャツ | 衣服          |         4000
 包丁           | キッチン用品  |         3000
 圧力鍋         | キッチン用品  |         6800
 フォーク       | キッチン用品  |          500
 おろしがね     | キッチン用品  |          880
(5 rows)

shop=#

shop=# -- 商品分類がキッチン用品で、かつ販売単価が2,000円以下の商品を検索 【AND】
shop=# SELECT shohin_mei, shohin_bunrui, hanbai_tanka FROM Shohin WHERE shohin_bunrui = 'キッチン用品' AND hanbai_tanka <= 2000;
 shohin_mei | shohin_bunrui | hanbai_tanka
------------+---------------+--------------
 フォーク   | キッチン用品  |          500
 おろしがね | キッチン用品  |          880
(2 rows)

shop=#

shop=# -- 商品分類がキッチン用品で、かつ販売単価が3,000円以上または登録日が2009年9月20日の商品を検索【ANDとOR両方使用】
shop=# SELECT * FROM Shohin WHERE shohin_bunrui = 'キッチン用品' AND ( hanbai_tanka >= 3000 OR torokubi = '2009-09-20');
 shohin_id | shohin_mei | shohin_bunrui | hanbai_tanka | shiire_tanka |  torokubi
-----------+------------+---------------+--------------+--------------+------------
 0004      | 包丁       | キッチン用品  |         3000 |         2800 | 2009-09-20
 0005      | 圧力鍋     | キッチン用品  |         6800 |         5000 | 2009-01-15
 0006      | フォーク   | キッチン用品  |          500 |              | 2009-09-20
(3 rows)

shop=#

論理演算子の結果はTRUE(真)/FALSE(偽)のどちらかの値(真理値)になり、その結果をまとめたものを真理表と言います。ただしNULL値は真偽判定されないためUNKNOWN(不明)となります。
例えば「X AND (Y OR Z)」の真理表は以下になります。

X Y Z Y OR Z X AND (Y OR Z)

書評

SELECT文を使用して、テーブル内の情報を検索する方法を学んだ。
WHERE句で条件を設定することでフィルタリングが可能で、その際に使用するのが算術演算子、比較演算子、論理演算子がある。

Discussion