1
1

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 1 year has passed since last update.

SQLの基本構文

Last updated at Posted at 2022-10-27

リレーショナルデータベースマネジメントシステム(RDBMS)

dataを表形式で管理→SQLでデータの登録・検索・更新・削除

  • Oracle Datebase
  • MySQL
  • Postgresql
  • SQLite

データベースの種類

  • リレーショナルデータベース:
  • 階層型データベース
  • ネットワーク型データベース

テーブル

テーブル:ある一定のまとまりのある、表形式のデータ群
カラム:縦方向、列のデータこと
レコード(ロウ):横方向、行のデータこと
フィールド:レコードを構成する1つ1つの要素。Excelでいうセル

カラム・レコード・フィールドの関係性は、複数のレコードの同じフィールドを集めたものがカラム
image.png

SQL構文

SELECT

何のデータをどのテーブルから取り出すのか?を考えると良い。

SELECT カラム名 FROM テーブル名;
  • データを複数抽出
    SELECT ID, user, post FROM post_table のように『,区切り』で複数抽出できる
  • カラム名を変更する
    SELECT ID, user as ユーザー名 FROM post_table のように『as』を使用すると変更して抽出できる
  • 全てのデータを抽出
    SELECT * FROM post_table のようにカラム名を『*』に変更すると全てのデータを抽出することができる

WHERE

特定の条件でデータを抽出する場合に使用

SELECT カラム名 FROM テーブル名 WHERE 条件式;

列指定はカラム名、行指定は条件式と覚えると良い
条件式には、イコールや大なり、小なり、否定などの式が入る

SELECT * FROM post_table WHERE user = taro;
上記SQL構文は、post_tableからuserがtaroのデータを全ての列で取得するとなる。

ORDER BY

抽出対象のデータの並び替え(昇順、降順)をするために使用できる。

SELECT カラム名 FROM テーブル名 ORDER BY 並べ替え条件式;

SELECT * FROM post_table ORDER BY created_at ASC;
上記SQL構文は、post_tableからすべてのカラムをcreated_atの昇順に取得するとなる。

昇順は、ASC(ASCはORDER BYのデフォルトが昇順なので省略できる)
降順は、DESC

  • 複数の条件式を指定できる
    SELECT * FROM post_table ORDER BY created_at, user_id DESC; 
    のように『,区切り』で指定できるが、先に書いたカラム名(ここではcreated_at)が優先される

  • WHEREとの組み合わせ
    SELECT * FROM post_table  WHERE user = taro ORDER BY created_at, user_id DESC;
    のようにWHEREと組み合わせることも可能。

構文の書き方で注意してほしいのは、ORDER BYは、FROMとWHEREのあとに書く。
ORDER BYは最後に書くと覚える。

GROUP BY

データをルールにしたがってグルーピングするもの。
SELECTにGROUP BYを付けることで、グルーピングしたいカラムをもとに、集約関数を使って合計や平均、最小値や最大値、カウントなどが計算できるようになる。

SELECT 
   グルーピングをするカラム,集約関数(集計対象カラム)
FROM 
   テーブル名 
WHERE 
   条件式 
GROUP BY 
   グルーピングをするカラム
ORDER BY 
   並べ替え条件式;

SELECT 商品分類,sum(売上金額) FROM product_table  GROUP BY 売上金額;
product_tableから商品分類ごとに売上金額を合計したデータを商品分類と一緒に抽出する。という意味になる。

  • ORDER BYとの組み合わせ
    SELECT 商品名,sum(売上金額) FROM product_table GROUP BY 商品名 ORDER BY sum(売上金額);
    product_tableから商品分類ごとに売上金額を合計したデータを商品分類の昇順で抽出する。となる。

  • 他の主な集計関数
    SELECT 商品, avg(売上金額), min(売上金額), max(売上金額) FROM product_table GROUP BY 商品名;
    avgは平均maxは最大値minは最小値を出力する。
    上記のように集計関数は複数あってもOK。

SELECT 商品, count (売上金額) FROM product_table GROUP BY 商品名;
グルーピングされたレコードの行数を取得する集約関数。
このSQLを実行すると、商品名の同じレコードがいくつあるのかを出力される。

また、count関数はテーブル内にいくつのレコードがあるのかを出力する場合もよく使用される。
SELECT count (*) FROM product_table;
カラム名を指定せずに*を指定すると、テーブルの全件データ数を取得できる。
テーブルの全件数を知りたい場合に頻繁に使用する。

HAVING

グルーピングされたデータの中から、さらに特定の条件でデータ抽出したいときに使用する。

SELECT 
   グルーピングをするカラム,集約関数(集計対象カラム)
FROM 
   テーブル名
WHERE 
   条件式
GROUP BY 
   グルーピングをするカラム
HAVING 
   集計関数(集計対象カラム)で条件式
ORDER BY 
   並べ替え条件式;

SELECT 商品名,sum(売上金額) FROM product_table GROUP BY 商品名 HAVING sum(売上金額) >= 100000;

上記SQLを実行すると、売上金額が10万円以上の商品名のみ抽出することができる。
HAVINGに集約関数を含んだカラムを直接条件式に入れ込むことで、HAVINGを元にしたデータ抽出できる。

  • WHEREとの違い
    WHEREが単純にテーブル内のデータを抽出。
    HAVINGはグルーピングしたデータからさらに抽出条件を付けられる。
    しかし、WHEREもHAVINGもやっていることは同じで、どちらもデータに対して抽出処理を実行される。
    異なるのは呼ばれるタイミングのみ。

【実行順番】
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY で、
『どのテーブルの(FROM)、どのデータを(WHERE)、どうグルーピングし(GROUP BY)、グルーピングしたデータをどう抽出し(HAVING)、どのカラム を(SELECT)、どう表示するか(ORDER BY)」の順番で実行。

WHEREはGROUP BYよりも前に、HAVINGはGROUP BYの後に実行される。
HAVINGは、GROUP BYされた後のデータに抽出条件を付与するため、集計関数を使用できる
WHEREは、GROUP BYされる前にデータに抽出条件を付与するため、集計関数を使用できない。

以上を踏まえ、下記のSQLを実行すると、
SELECT 商品名 , sum(売上金額) FROM product_table WHERE 商品名 !='パンツ' GROUP BY 商品名 HAVING sum(売上金額) <= 100000;

パンツ以外の売上金額の合計を集計し、売上金額が10万円以下のみのデータを抽出される。

JOIN

テーブルとテーブルを結合する

JOINの種類

  • 内部結合
    inner join
  • 外部結合
    left join
    right join
    outer join

内部結合では、on句で指定した条件に一致するレコードのみSQLの実行結果に表示
外部結合ではon句で指定した条件に一致しないレコードも実行結果に表示され、FROMを指定したテーブルのレコードをすべて抽出される。

INNER JOIN

SELECT カラム名
FROM テーブル名A(テーブル名 as Aの意味)
INNER JOIN テーブル名B(テーブル名 as Bの意味) → FROMとWHEREの間に記述
ON A.キー = B.キー → 「どのカラムで結合するか」を指定
WHERE 条件式;

例)
テーブル1:testA

氏名 出席番号 数学
鈴木 1 50
佐藤 2 60
高橋 3 40
田中 4 80

テーブル2:testB

氏名 出席番号 国語
鈴木 1 70
佐藤 2 60
伊藤 5 80
渡邊 6 50
SELECT 
   A.氏名, A.数学, B.国語
FROM 
   testA as A → 別名をつけている
INNER JOIN 
   testB as B → 別名をつけている
ON 
   A.氏名 = B.氏名

上記のSQLを実行すると

氏名 出席番号 数学 国語
鈴木 1 50 70
佐藤 2 60 60

ベン図
image.png

SELECTのA.氏名は「testAテーブルの氏名のカラム」
A.数学は「testAテーブルの数学のカラム」
B.国語は、「testBテーブルの国語のカラム」からデータを取得し、両方のテーブルからデータを同時に取得できるようになる。
ONは、どのカラムで結合するかを指定するので、
A.氏名でtestAテーブルのカラムの氏名、B.氏名でtestBテーブルのカラムの氏名をキーにして結合
それぞれのテーブルの氏名では、鈴木と佐藤が共通するレコードなので、この2つのレコードが抽出される。

LEFT JOIN

SELECT カラム名
FROM テーブル名A(テーブル名 as Aの意味)
LEFT JOIN テーブル名B(テーブル名 as Bの意味) → FROMとWHEREの間に記述
ON A.キー = B.キー → 「どのカラムで結合するか」を指定
WHERE 条件式;

例)
テーブル1:testA

氏名 出席番号 数学
鈴木 1 50
佐藤 2 60
高橋 3 40
田中 4 80

テーブル2:testB

氏名 出席番号 国語
鈴木 1 70
佐藤 2 60
伊藤 5 80
渡邊 6 50
SELECT *  → すべてのカラムを指定
FROM testA A → 別名をつけている
LEFT JOIN testB B → 別名をつけている
ON A.氏名 = B.氏名 → 両方のテーブルに存在する氏名のカラムを指定

上記のSQLを実行すると

氏名 出席番号 数学 氏名 出席番号 国語
鈴木 1 50 鈴木 1 70
佐藤 2 60 佐藤 2 60
高橋 3 40 NULL NULL NULL
田中 4 80 NULL NULL NULL

ベン図
image.png

このようにLEFT JOINでは、testAのテーブル(FROMで指定したテーブル)を基準として、もう1つのテーブルを結合させる。
on句で指定した氏名で、キーとして結合できなかったレコードはNULLとして補完される。

RIGHT JOIN(外部結合)

SELECT カラム名
FROM テーブル名A(テーブル名 as Aの意味)
RIGHT JOIN テーブル名B(テーブル名 as Bの意味) → FROMとWHEREの間に記述
ON A.キー = B.キー → 「どのカラムで結合するか」を指定
WHERE 条件式;

例)
テーブル1:testA

氏名 出席番号 数学
鈴木 1 50
佐藤 2 60
高橋 3 40
田中 4 80

テーブル2:testB

氏名 出席番号 国語
鈴木 1 70
佐藤 2 60
伊藤 5 80
渡邊 6 50
SELECT *  → すべてのカラムを指定
FROM testA A → 別名をつけている
RIGHT JOIN testB B → 別名をつけている
ON A.氏名 = B.氏名 → 両方のテーブルに存在する氏名のカラムを指定

上記のSQLを実行すると

氏名 出席番号 数学 氏名 出席番号 国語
鈴木 1 50 鈴木 1 70
佐藤 2 60 佐藤 2 60
NULL NULL NULL 伊藤 5 80
NULL NULL NULL 渡辺 6 50

ベン図
image.png

このようにRIGHT JOINでは、testBのテーブル(RIGHT JOINで指定したテーブル)を基準として、もう1つのテーブルを結合させる。
on句で指定した氏名で、キーとして結合できなかったレコードはNULLとして補完される。

LEFT JOIN、RIGHT JOINは相互に書き換え可能なため、自分が使いやすい方を使用して構わない。
混在させてはいけない。

FULL OUTER JOIN(OUTER JOIN)

SELECT カラム名
FROM テーブル名A(テーブル名 as Aの意味)
OUTER JOIN テーブル名B(テーブル名 as Bの意味) → FROMとWHEREの間に記述
ON A.キー = B.キー → 「どのカラムで結合するか」を指定
WHERE 条件式;

テーブル1:testA

氏名 出席番号 数学
鈴木 1 50
佐藤 2 60
高橋 3 40
田中 4 80

テーブル2:testB

氏名 出席番号 国語
鈴木 1 70
佐藤 2 60
伊藤 5 80
渡邊 6 50
SELECT *  → すべてのカラムを指定
FROM testA A → 別名をつけている
OUTER JOIN testB B → 別名をつけている
ON A.氏名 = B.氏名 → 両方のテーブルに存在する氏名のカラムを指定

上記のSQLを実行すると

氏名 出席番号 数学 氏名 出席番号 国語
鈴木 1 50 鈴木 1 70
佐藤 2 60 佐藤 2 60
高橋 3 40 NULL NULL NULL
田中 4 80 NULL NULL NULL
NULL NULL NULL 伊藤 5 80
NULL NULL NULL 渡辺 6 50

ベン図
image.png
このようにOUTER JOINでは、すべてのレコードが表示される。
on句で指定した氏名で、キーとして結合できなかったレコードはNULLとして補完される。

AND演算子 OR演算子(論理演算子)

2つ以上の条件式を組み合わせてデータ抽出を行う際に使用

AND

SELECT カラム名
FROM テーブル名
WHERE 条件式A AND 条件式B; → 条件式Aかつ条件式Bという条件が成立

例)

SELECT
    *
FROM
    product_table
WHERE
    商品分類 ='パンツ' AND 単価 >= 5000;

上記のSQLを実行すると・・・
『商品分類がパンツ』、『単価が5000円以上』の両方を満たすレコードが抽出される。

ベン図
image.png

OR

SELECT カラム名
FROM テーブル名
WHERE 条件式A OR 条件式B; → 条件式Aまたは条件式Bという条件が成立

例)

SELECT
    *
FROM
    product_table
WHERE
    商品分類 ='パンツ' OR 単価 >= 5000;

上記のSQLを実行すると・・・
『商品分類がパンツ』、『単価が5000円以上』のどちらかを満たすレコードがすべて抽出される。

ベン図
image.png

AND演算子とOR演算子を併用する場合

AND演算子がOR演算子よりも優先されるため、注意が必要

例)
『商品分類がパンツ』または、『単価が5,000円以上』かつ『売上金額が500,000円以上』という条件で抽出したい場合
下記のSQLを実行する

SELECT
    *
FROM
    product_table
WHERE
    (商品分類 ='パンツ' OR 単価 >= 5000) AND 売上金額 >= 500000;

()の中の条件式が優先されるため、意図した通りに実行結果が得られる。

LIKE演算子

パターンマッチングを行い、
データ群の中からある特定のパターンに一致あるいは類似するデータを探し出すことができる。

SELECT カラム名
FROM テーブル名
WHERE カラム LIKE パターンマッチングの条件; → ワイルドカードを使用する

ワイルドカード
_ (アンダーバー) : 任意の1文字の文字列(文字数を指定したい場合に使用)
% : 0文字以上の任意の文字列

例)テニスボール、サッカーボール、バレーボール、ボウリングと4つの球があったとする。
『%ボール』とすると・・・テニスボール、サッカーボール、バレーボールの3つの球が抽出される。
『___(アンダーバー3つ)ボール』とすると・・・テニスボール、バレーボールの2つのみ抽出される。

前方一致

例)
countryテーブル

ID 国名 首都
Argentina Buenos Aires
Australia Canberra
Belgium Brussels
Japan Tokyo
China Beijing

国名が『A』から始まるレコードを抽出する場合

SELEC  *
FROM country
WHERE 国名 LIKE ‘A%’;

上記のSQLを実行すると・・・Argentina、Australiaの2つの国が抽出される

後方一致

例)
countryテーブル

ID 国名 首都
Argentina Buenos Aires
Australia Canberra
Belgium Brussels
Japan Tokyo
China Beijing

国名が『a』で終わるレコードを抽出する場合

SELEC  *
FROM country
WHERE 国名 LIKE ‘%a’;

上記のSQLを実行すると・・・Argentina、Australia、Chinaの3つの国が抽出される

前方一致かつ後方一致

例)
countryテーブル

ID 国名 首都
Argentina Buenos Aires
Australia Canberra
Belgium Brussels
Japan Tokyo
China Beijing

国名が『C』から始まり、『a』で終わるレコードを抽出する場合

SELEC  *
FROM country
WHERE 国名 LIKE ‘A%a’;

上記のSQLを実行すると・・・Chinaのみ抽出される

部分一致

例)
countryテーブル

ID 国名 首都
Argentina Buenos Aires
Australia Canberra
Belgium Brussels
Japan Tokyo
China Beijing

国名に『a』を含むレコードを抽出する場合

SELEC  *
FROM country
WHERE 国名 LIKE ‘%a%’;

上記のSQLを実行すると・・・Argentina、Australia、Japan、Chinaの4つの国が抽出される

NOT LIKE

例)
countryテーブル

ID 国名 首都
Argentina Buenos Aires
Australia Canberra
Belgium Brussels
Japan Tokyo
China Beijing

国名に『a』を含まないレコードを抽出する場合

SELEC  *
FROM country
WHERE 国名 NOT LIKE ‘%a%’;

上記のSQLを実行すると・・・Belgiumのみが抽出される

ワイルドカードのエスケープ処理

例)
productテーブル

ID 商品ID 商品
A_1000 Tシャツ
A_2000 ジーンズ
A_2010 ショートパンツ
B_1000 ロングパンツ
B_1010 ダウンジャケット

商品IDに『_1』を含むレコードを抽出する場合

SELEC  *
FROM  product
WHERE 商品ID LIKE ‘%?_1%’ ESCAPE ‘?’;

上記のSQLを実行すると・・・A_1000のみが抽出される

ワイルドカードの『 % 』や『 _ 』は、特殊文字になるため、
WHERE 商品ID LIKE ‘%_1%’このような記述では意図したレコードは抽出されない。
エスケープ処理を忘れないように。

特殊文字とは・・・
プログラム上で何らかの意味を持ち、そのままでは文字列として扱われない文字のこと

BETWEEN

範囲指定をするときに使用。
範囲指定できるもの:数値・日付・時間・文字列など

SELECT カラム名
FROM テーブル名
WHERE カラム名 BETWEEN 下限値 AND 上限値;

上記構文は、

SELECT カラム名
FROM テーブル名
WHERE カラム名 >= 下限値 AND [カラム名] <= 上限値;

と同様になるため、指定範囲の値を条件として抽出できる。

NOT BETWEEN

SELECT カラム名
FROM テーブル名
WHERE カラム名 NOT BETWEEN 下限値 AND 上限値;

指定範囲外の値を条件にして抽出できる。

例)bakery_shop

商品名 売上金額 売上日
クリームパン 5,000 2022-10-17
食パン 3,000 2022-10-25
あんぱん 6,000 2022-10-07
カレーパン 4,000 2022-10-30
メロンパン 3,500 2022-11-01

『売上金額が、4,000円以上6,000円以下』のデータを抽出するには下記のSQLを実行する。

SELECT 商品名, 売上金額 FROM bakery_shop WHERE 売上金額 BETWEEN 4000 AND 6000;

実行結果は下記になる。

商品名 売上金額
クリームパン 5,000
カレーパン 4,000
あんぱん 6,000

『売上日が、2022-10-17から2022-10-30まで』のデータを抽出するには下記のSQLを実行。

SELECT * FROM bakery_shop WHERE 売上日 BETWEEN ‘2022-10-17’ AND ‘2022-10-30’;

実行結果(すべてのカラムを選択しているので、売上金額も抽出される)

商品名 売上金額 売上日
クリームパン 5,000 2022-10-17
食パン 3,000 2022-10-25
カレーパン 4,000 2022-10-30

『売上金額が、4,000円以上6,000円以下』以外のデータを抽出するには下記のSQLを実行する。

SELECT 商品名, 売上金額 FROM bakery_shop WHERE 売上金額 NOT BETWEEN 4000 AND 6000;

実行結果は下記になり、NOT BETWEENは指定された範囲外の抽出に使用できる。

商品名 売上金額
食パン 3,000
メロンパン 3,500

LENGTH関数

LENGTH関数は、引数に指定した文字列の文字数を取得

LENGTH(引数)
引数・・・文字列:文字数
     BLOB型:バイト数
     上記以外:文字列型に変換した文字数
     NULL:NULL

BLOB型はバイナリデータの格納に使用されるデータ型で、BLOBとはBinary Large Objectという意味。

BLOB型の例は、画像や音声などのマルチメディアオブジェクトをバイナリデータに変換したもの。

引数が文字列やBLOB型でない場合は、一度文字列に変換したうえで文字数を取得。

引数がNULLの場合は、NULLが返ってくる。

SELECT LENGTH(カラム) → カラムの値の文字数を取得
FROM テーブル;

例)bakery_shop

商品名 売上金額 売上日
クリームパン 5,000 2022-10-17
あんぱん 6,000 2022-10-07
カレーパン 4,000 2022-10-30
メロンパン 3,500 2022-11-01
SELECT 
    商品名, LENGTH(商品名)文字数 → 商品名のカラムと商品名の文字数を新しいカラムの『文字数』で取得
FROM 
    bakery_shop;

上記SQLを実行

商品名 文字数
クリームパン 6
あんぱん 4
カレーパン 5
メロンパン 5

指定した文字数以上のデータを抽出する場合は、条件抽出するためのWHERE句で使用

SELECT 
   商品名, LENGTH(商品名)文字数
FROM 
   bakery_shop
WHERE
   LENGTH(商品名) >= 5; → 5文字以上のデータを抽出する

SQLを実行

商品名 文字数
クリームパン 6
カレーパン 5
メロンパン 5

5文字以上のデータを抽出された。

DISTINCT

値の重複を排除してカラムを抽出したいときに使用。

SELECT 
   distinct カラム1, カラム2,… → distinctを使って抽出したカラムは一意の値だけ残る
FROM 
   テーブル;

例) foods_table

商品分類 商品名 価格
パン カレーパン 200
弁当 からあげ弁当 500
パン カレーパン 150
飲料 100

SELECT distinct 商品分類 FROM foods_table;
を実行すると

商品分類
パン
弁当
飲料

のように、値の重複(パンとパン)を排除して抽出される。

SELECT distinct 商品分類, 商品名 FROM foods_table;
と複数カラムを指定することもできる。
上記を実行すると

商品分類 商品名
パン カレーパン
弁当 からあげ弁当
飲料

のように、値の重複(パンとパン、カレーパンとカレーパン)を排除して抽出される。

count関数と併用することもできる
SELECT count(distinct 商品分類) FROM foods_table;
を実行すると

count(distinct 商品分類)
3

となり、商品分類の重複を排除した『パン・弁当・飲料』の3種類存在するため、3という値が抽出される。

GROUP BYとの違い
DISTINCTは、『重複した値を排除』
GROUP BY句は、『重複した値を一つにまとめる』というイメージ。

例)

  • DISTINCT
    SELECT distinct 商品分類 FROM foods_table;
  • GROUP BY
    SELECT 商品分類 FROM foods_table GROUP BY 商品分類;

上記SQL構文は、下記の結果になり、同じ結果が得られる。

商品分類
パン
弁当
飲料

DISTINCTもGROUP BYも一意の値が抽出されるのは、変わらないため、値の重複なしで抽出される。
しかし、GROUP BY句を使った集計関数は、DISTINCTで書き換えることはできない。

SELECT 商品分類, sum(価格) FROM foods_table GROUP BY 商品分類;

のように、GROUP BY句で商品分類のカラムを指定して、商品分類のカラムの値ごとに価格のカラムをSUM関数で集計する処理は、DISTINCTでは向いていないため、GROUP BY句を使いましょう。

SUBSTRING関数

対象の文字列から、開始位置と文字数を指定して、一部文を切り出すことができる関数。

substring(文字列(もしくは、カラム名), 開始位置, 文字数)

第一引数:対象の文字列もしくは、カラムを指定。
第二引数:文字列を切り出す開始位置を整数で指定。
第三引数:開始位置から切り出したい文字数を指定。

第二引数について
+3であれば、最初の文字を1番目と数え、3文字目が開始位置になる。
-3であれば、最後の文字を1番目と数え、3文字前が開始位置になる。

例)bakery_shop

商品名 売上金額 売上日
クリームパン 5,000 2022-10-17
あんぱん 6,000 2022-10-07
カレーパン 4,000 2022-11-02
メロンパン 3,500 2022-11-30

売上日の月ごとの売上金額の合計を出したい場合

SELECT
   substring(“売上日”, 6, 2) as 月,
   sum(“売上金額”) as 売上合計
FROM
   bakery_shop
GROUP BY 月;

上記SQLを実行すると

売上金額
10 11,000
11 7,500

売上金額を月ごとに集計できた。

ROUND関数

数値を指定した桁数の四捨五入に使用。

ROUND(数値, 桁数)

第一引数:四捨五入の対象となる数値もしくはカラムを指定
     カラムを指定した場合、カラムのすべての数値が四捨五入の対象になる。
第二引数:四捨五入を行う桁数を指定
     桁数を指定しない場合、0が指定されたものとなり整数が表示される

第一引数、第二引数のどちらかにNULLが入ると、NULLを返す

例)test-results_table
あるクラスのテスト結果の平均点数を表すテーブル

科目名 平均点数
数学 60.25
国語 72.333
社会 65.5
英語 55.2
化学 58.25
  • 少数を省力し、整数のみ表示する場合
SELECT 
科目名,平均点数, ROUND(平均点数) as 四捨五入値 → 第二引数を省略もしくは0とする
FROM
   test-results_table;

上記SQLを実行すると

科目名 平均点数 四捨五入値
数学 60.25 60
国語 72.333 72
社会 65.5 66
英語 55.2 55
化学 58.25 58

第一小数点が四捨五入され、整数のみ抽出される。

  • 第一小数点まで表示する
SELECT 
科目名,平均点数, ROUND(平均点数, 1) as 四捨五入値 → 第二引数を1とする
FROM
  test-results_table;

上記SQLを実行すると

科目名 平均点数 四捨五入値
数学 60.25 60.3
国語 72.333 72.3
社会 65.5 65.5
英語 55.2 55.2
化学 58.25 58.3

第二小数点が四捨五入され、第一小数点でまで表示される。

  • 第二小数点まで表示する
SELECT 
科目名,平均点数, ROUND(平均点数, 2) as 四捨五入値 → 第二引数を2とする
FROM
  test-results_table;

上記SQLを実行すると

科目名 平均点数 四捨五入値
数学 60.25 60.25
国語 72.333 72.33
社会 65.5 65.5
英語 55.2 55.2
化学 58.25 58.25

第三小数点が四捨五入され、第二小数点まで表示される。

CASE式

If Else構文のような条件分岐を行いたいときに使用。

CASE式には2種類の条件分岐の式がある。
単純CASE式
カラムの値が指定した値と等価であるか判定し、処理の分岐を行う。

CASE カラム → 対象になるカラムを書く
    WHEN 値1 THEN 結果1 → カラムの値に基づき処理を分岐(WHEN句に等価の場合、THENの値)
    WHEN 値2 THEN 結果2
    WHEN 値3 THEN 結果3
  ELSE 結果4 → WHEN句で指定した値のどれも一致しない場合の結果を、ELSE句に書く
END

検索CASE式
等価判定以外にもさまざまな条件で処理を分岐させる。

CASE → 対象となるカラムを書かない
    WHEN 条件式1 THEN 結果1 → WHEN句で条件式を書いて、条件式がtrueのときTHENを返す
    WHEN 条件式2 THEN 結果2
    WHEN 条件式3 THEN 結果3
  ELSE 結果4
END

例)test-results_table
あるクラスのテスト評価を氏名ごとに記載されたテーブル

氏名 英語(5点評価)
田中 5
鈴木 3
高橋 3
伊藤 1
佐藤 4

評価に基づいて成績を1であればC、5であればA、それ以外であればBと振り分けるとする。

  • 単純CASE式の場合
SELECT *
      CASE 英語 → 対象カラムを書く
     WHEN 1 THEN ‘C’
     WHEN 5 THEN ‘A’
      END 成績 → 別名をつける場合はENDの後に
FROM test-results_table;
氏名 英語(5点評価) 成績
田中 5 A
鈴木 3 B
高橋 3 B
伊藤 1 C
佐藤 4 B

このように、条件通り抽出できる。

  • 検索CASE式の場合
SELECT *
      CASE
     WHEN 英語 = 1 THEN ‘C’ → 条件式にカラムを指定する
     WHEN 英語 = 5 THEN ‘A’
      END 成績 → 別名をつける場合はENDの後に
FROM test-results_table;
氏名 英語(5点評価) 成績
田中 5 A
鈴木 3 B
高橋 3 B
伊藤 1 C
佐藤 4 B

このように、条件通り抽出できる

  • CASE式を入れ子として使用する
    products_table
商品名 売上日 売上金額
ロングパンツ 2022-10-20 9000
ジーンズ 2022-10-05 10000
セーター 2022-11-10 3000
ジャケット 2022-11-15 2000
ショートパンツ 2022-10-01 2000

10月中の売上に対してのみ、売上金額が1万円以上には、3,000円のキャッシュバック、8,000円以上には2,000円のキャッシュバック、それ以外は500円のキャッシュバック、10月以外はキャッシュバックを0とする。

SELECT *
     CASE
        WHEN 売上日 BETWEEN ‘2022-10-1’ AND ‘2022-10-31’ THEN
            CASE
               WHEN 売上金額 >= 10000 THEN 3000
               WHEN 売上金額 >= 8000 THEN 2000
               ELSE 0
            END
         ELSE 0
     END キャッシュバック
FROM products_table;

上記SQL実行すると

商品名 売上日 売上金額 キャッシュバック
ロングパンツ 2022-10-20 9000 2000
ジーンズ 2022-10-05 10000 3000
セーター 2022-11-10 3000 0
ジャケット 2022-11-15 2000 0
ショートパンツ 2022-10-01 2000 500

想定通りの結果が得られた。
このように、CASE式を入れ子にすることも可能。

サブクエリ

一つのSQLの実行結果をもとに、また別のSQLで抽出を行いたい時、
2段階以上の集計を1つのクエリに簡単にまとめることができる。

サブクエリは、1つのSQLをカッコで括ったもの。

SELECT 
   カラムA, SUM(カラムB<integer>)
FROM
   (SELECT  → サブクエリ
      カラムA, カラムB<integer>
    FROM 
      テーブル
    WHERE 
      条件式)
GROUP BY カラムA

テーブルからAというカラムとBという数値が入ったカラムを条件式によって抽出され、FROM句でカラムAごとの数値の合計を計算。

SELECT 
   テーブルC.カラムA,
   テーブルC.カラムB,
   テーブルD.カラムE
FROM
  (SELECT  → サブクエリ
      カラムA,カラムB
   FROM 
      テーブルC
   WHERE 
      条件式)
JOIN 
   テーブルD
ON 
  テーブルC.カラムA = テーブルD.カラムA;

テーブルCからカラムAとBを抽出、これをJOIN句でテーブルDと結合し、テーブルCとカラムAとB、テーブルDのカラムEを抽出している。

例)
テーブル1:testA

氏名 出席番号 数学
鈴木 1 50
佐藤 2 60
高橋 3 40
田中 4 80

テーブル2:testB

氏名 出席番号 数学
鈴木 1 70
佐藤 2 60
高橋 3 80
田中 4 50

数学の点数が60点以下の人の国語の点数がいくつなのか抽出するには、以下のSQLを実行する

SELECT 
    testA.氏名,
    testB.出席番号,
    数学,
    国語
FROM
   (SELECT → testAのテーブルから数学の点数が60点以下の人を抽出
      *
    FROM 
      testA
    WHERE 
      数学 <= 60) 
    testA
JOIN  → testBのテーブルを、どちらのテーブルにもある出席番号で結合
    testB
on 
    testA.出席番号 = testB.出席番号;
氏名 出席番号 数学 国語
鈴木 1 50 70
佐藤 2 60 60
高橋 3 40 80

となり、サブクエリの条件式を加えたデータ抽出が行える。

IN句

複数のOR条件を1つにまとめて記述でき、
カラムの値が指定した値のリストのいずれかに一致するという条件を作ることができる。

SELECT 
   * 
FROM 
   テーブル
WHERE 
   カラム IN (値1,値2,値3...);

WHERE句で条件を適用するカラムを記述し、IN句を記述する。

逆に、値のいずれにも一致しないという条件は下記になる。

SELECT 
   * 
FROM 
   テーブル
WHERE 
   カラム NOT IN (値1,値2,値3...); → カッコ内のカラムの値がいずれかに一致するとなる

例)
テーブル1:testA

氏名 出席番号 数学
鈴木 1 50
佐藤 2 60
高橋 3 40
田中 4 80

氏名が鈴木、佐藤、今野のいずれかで当てはまるレコードを抽出したい場合

SELECT
     *
FROM
     testA
WHERE
     氏名 IN(‘鈴木’, ‘佐藤’, ‘今野’); → WHERE句にIN句で複数の条件を指定する

上記SQLを実行すると

氏名 出席番号 数学
鈴木 1 50
佐藤 2 60

IN句で指定した条件のみ抽出される。

氏名が鈴木、佐藤、今野のいずれかにも当てはまらないレコードを抽出したい場合

SELECT
     *
FROM
     testA
WHERE
     氏名 NOT IN(‘鈴木’, ‘佐藤’, ‘今野’); → WHERE句にIN句で複数の条件を指定する
氏名 出席番号 数学
高橋 3 40
田中 4 80

と氏名が鈴木、佐藤、今野以外の氏名の方が抽出される。

サブクエリを使用する場合

テーブル1:testA

氏名 出席番号 数学
鈴木 1 50
佐藤 2 60
高橋 3 40
田中 4 80

テーブル2:testB

氏名 出席番号 国語
鈴木 1 70
佐藤 2 60
高橋 3 80
田中 4 50

testBで国語の点数が70点以上のtestAの氏名のいずれかに一致するというレコードを抽出したい場合

SELECT 
  *
FROM
    testA
WHERE
   氏名 IN(SELECT 氏名 FROM testB WHERE 国語 >= 70); → サブクエリで、testBの国語の点数が70点以上の氏名を抽出
氏名 出席番号 数学
鈴木 1 50
高橋 3 40

国語の点数が70点以上は、鈴木と高橋のみであるため、上記のレコードが抽出される。

LIMIT

SQLを実行する時に取得するデータの最大数を設定できる関数。

SELECT
    カラム名
FROM
  テーブル
LIMIT
  設定レコード数; → LIMIT関数で設定したレコードより少ない場合、全データが抽出される

OFFSET関数との組み合わせ

OFFSET関数は、データを取得する開始位置を指定することができる関数のこと

SELECT 
    カラム名
FROM
  テーブル
LIMIT
  設定レコード数 OFFSET 取得開始行 - 1; → 取得したい行数からマイナス1した数を指定

例)
「売上金額の合計」が高い商品順の4番目から3レコードのデータを抽出したい場合

SELECT
    商品名, 
SUM(売上金額) as 売上合計 → 売上金額の合計を抽出
FROM
  Products_table
GROUP BY
    商品名 → 売上金額を商品ごとにグループにして集計
ORDER BY 
  売上合計 desc → 売上金額を高い順に並び替える
LIMIT 3 OFFSET 3; → レコード数を3、4番目を開始位置として指定したいので、4番目のマイナス1である3を指定
1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?