順番に読み進めながら学べます

関数 ③ — 数学関数(ROUND / FLOOR / CEILING)と COALESCE

この記事は、基礎から複雑なSQL,SQLチューニングまでSQLの実践的なスキルを1からマスターする「SQL入門講座の一部」です。
ROUND/FLOOR/CEILING/POWERの数学関数と、NULLでない最初の値を返すCOALESCEを、CSVの社員・テストスコアデータで実行しながら学べます。

本記事で使うデータ — staff と test_score

関数記事の最後は数学関数COALESCEです。数学関数ではsalary列のような数値の四捨五入・切り捨て・切り上げ・べき乗を、COALESCE ではNULL を別の値に置き換える書き方を扱います。

本記事では 2 つの CSV を使い分けます。前半の数学関数は前回までと同じstaffテーブル(社員 10 名)、後半の COALESCE は新たにtest_scoreテーブル(学生 8 名 / テスト 1〜3 回 / NULL を含む)を読み込みます。test_score のscore_1 / score_2 / score_3には欠席のため未受験のセルが NULL として入っており、「最初に受験できたテストの点数を最終評価とする」のような実務シナリオで COALESCE の使い方を学びます。

演習に入る前に、本記事で使う 2 つのテーブル — stafftest_score — の列定義データのサンプルを確認しておきます。

PRAGMA table_info(staff);PRAGMA table_info(test_score);で両テーブルの列定義を確認してください。

SELECT * FROM staff LIMIT 5;SELECT * FROM test_score LIMIT 5;で先頭 5 行のデータをプレビューしてください。

SQL エディタ

クエリを実行してください

数学関数 — ROUND / FLOOR / CEILING / POWER

数値を整える代表的な関数は次の 4 つです。

- ROUND(x, n): 小数点以下 n 桁で四捨五入。n を省略すると整数に丸める

- FLOOR(x): 切り捨て(負の無限大方向に丸める)

- CEILING(x)またはCEIL(x): 切り上げ(正の無限大方向に丸める)

- POWER(x, y): べき乗(x の y 乗)

-- 1) ROUND: 四捨五入
SELECT ROUND(3.14);          -- 3 (整数)
SELECT ROUND(3.14, 1);       -- 3.1 (小数点以下 1 桁)

-- 2) FLOOR: 切り捨て
SELECT FLOOR(3.84);          -- 3
-- ※ CEILING は MySQL / PostgreSQL / Oracle / SQL Server で SELECT CEILING(3.14); → 4 を返す

-- 3) POWER: べき乗
SELECT POWER(3, 4);          -- 81 (3 の 4 乗)
SELECT POWER(2, 10);         -- 1024

-- 4) 列を使った例 — 月給を四捨五入
SELECT name, salary, ROUND(salary / 12.0) AS monthly
FROM staff;
入力ROUND (四捨五入)FLOOR (切り捨て)CEILING (切り上げ / 本講座のコンソールでは未対応)
3.14334
3.84434
3.50434
-3.14-3-4 (負方向)-3

「年俸を 12 で割って月給に直し、四捨五入で整数表示したい」という要件を想定します。(正しく実行できれば解説が表示されます)

staffテーブルからnamesalaryROUND(salary / 12.0)をmonthlyという別名で、計 3 列を取り出してください。

monthlyの降順で並べてください。

③ 結果が 10 行になり、先頭が Frank Tanaka 7,200,000 / 600,000 になることを確認してください。

SQL エディタ

クエリを実行してください

「現在の年俸から、毎年 10% ずつ昇給した場合の 3 年後の年収を試算したい」という要件を想定します。同じ倍率を複数回掛ける計算はPOWER(x, y)(x の y 乗)を使うと 1 つの式で表せます。3 年連続で 1.1 倍する計算ならsalary * POWER(1.1, 3)で書け、結果はsalary * 1.331と同じ値になります。

staffテーブルからnamesalary、*`ROUND(salary POWER(1.1, 3))salary_after_3y`という別名で**、計 3 列を取り出してください(小数が出ないよう ROUND で整数に丸めます)。

`salary_after_3y`の降順で並べ、先頭 5 行に絞ってください。

③ 結果が 5 行になり、先頭が Frank Tanaka 7,200,000 / 9,583,200、2 行目が David Sato 6,800,000 / 9,050,800 になることを確認してください。

SQL エディタ

クエリを実行してください

「月給の表示で四捨五入と切り捨てで結果がどう変わるか確かめたい」という要件を想定します。2 つの丸め関数を同じ式に並べて結果を見比べ、各関数の挙動の違いを目視で確認しましょう。

staffテーブルからnamesalaryROUND(salary / 12.0)をround_monthlyFLOOR(salary / 12.0)をfloor_monthlyの計 4 列を取り出してください。

salaryの昇順で並べ、先頭 5 行に絞ってください。

③ 結果が 5 行になり、Emi / Carol / Iris / Alice / Bob の順で並ぶこと、Alice(給料が 12 で割り切れる)以外はround_monthlyfloor_monthlyの値がずれている(端数の有無で挙動が違う)ことを確認してください。

SQL エディタ

クエリを実行してください

COALESCE — NULL でない最初の値を返す

COALESCE(値1, 値2, 値3, ...)は、引数を左から順に評価し、最初の NULL でない値を返す関数です。すべて NULL なら NULL を返します。「メインの列に値があればそれを、なければ予備の列を、それも無ければデフォルト値を」というNULL の代替値を取り出すパターンで使います。

本記事ではtest_scoreテーブルを題材にします。student_idごとにscore_1 / score_2 / score_3(1 回目〜3 回目のテスト点数)が並び、欠席で未受験の回は NULL になっています。COALESCE で(score_1, score_2, score_3, 0)を渡すと、初めて受験できたテストの点数を「最終評価点」として取り出せます。0 を末尾に置けば「全部欠席なら 0 点扱い」になります。

COALESCE の動き — 左から最初の非 NULL を返す
引数選ばれる値意味(85, 92, 78)851 つ目が非 NULLならそれを返す(NULL, 78, 88)781 つ目が NULL なので2 つ目を返す(NULL, NULL, 95)951, 2 つ目が NULL なので3 つ目を返す(NULL, NULL, NULL)NULL全部 NULL ならNULL を返す
引数を左から順に評価し、最初に見つかった NULL 以外の値が返されます。最後にリテラル値(0 や 'unknown' など)を置くとデフォルト値になります。
-- 1) リテラルでの確認
SELECT COALESCE(NULL, NULL, 'C');         -- 'C'
SELECT COALESCE(NULL, NULL, NULL);        -- NULL

-- 2) test_score テーブルで最終評価点を取り出す
SELECT student_id, name, score_1, score_2, score_3,
       COALESCE(score_1, score_2, score_3) AS first_score
FROM test_score;

-- 3) デフォルト値で「全部欠席なら 0 点」にする
SELECT student_id, name,
       COALESCE(score_1, score_2, score_3, 0) AS final_score
FROM test_score;

2 引数版は IFNULL でも書ける

「NULL ならデフォルト値、そうでなければ元の値」のような2 引数だけの NULL 置換なら、IFNULL(列, デフォルト)でも同じ意味になります(本講座のコンソール / MySQL の両方でサポート)。たとえばCOALESCE(email, '未登録')IFNULL(email, '未登録')は完全に同じ結果です。

3 引数以上が必要なときはCOALESCEを使います。COALESCEは SQL 標準なので、PostgreSQL / Oracle / SQL Server などでも同じ書き方が通用し、移植性が高い選択になります。

「テストを 3 回実施したが、欠席があるため最初に受験できた回の点数を最終評価点としたい」という要件を想定します。

test_scoreテーブルからstudent_idnamescore_1score_2score_3COALESCE(score_1, score_2, score_3)をfirst_scoreという別名で、計 6 列を取り出してください。

② 結果が 8 行になり、Alice は 85(score_1 が非 NULL)、Bob は 78(score_1 が NULL なので score_2 が選ばれる)、Carol は 95(score_1 と score_2 が NULL なので score_3)、Dave は NULL(すべて NULL)になることを確認してください。

SQL エディタ

クエリを実行してください

「全員に最終評価点を付けたい。欠席が続いた学生は 0 点扱いとし、点数の高い順に上位 3 名を表彰したい」という要件を想定します。

test_scoreテーブルからstudent_idnameCOALESCE(score_1, score_2, score_3, 0)をfinal_scoreという別名で、計 3 列を取り出してください。

final_scoreの降順で並べ、先頭 3 行に絞ってください。

③ 結果が 3 行(Carol 95 / Frank 90 / Grace 88)になることを確認してください。

SQL エディタ

クエリを実行してください
QUIZ

理解度チェック

まずは1問ずつ答えてみましょう。

Q1次のうち、SELECT ROUND(3.84);の結果として正しいものはどれですか。

Q2SELECT FLOOR(3.84), CEILING(3.14);の結果として正しいものはどれですか。

Q3SELECT COALESCE(NULL, NULL, 'C', 'D');の結果として正しいものはどれですか。