この記事について
第4章では、SELECT文の中で使える単一行関数を整理します。文字列を変換する関数・数値を計算する関数・日付を操作する関数の3カテゴリを、構文と実行例つきで解説します。
ファンクション(関数)の基礎知識
ファンクションとは「引数を渡すと、決まった処理をして結果を返す仕組み」です。
-- 基本構文
ファンクション名(引数1, 引数2, ...)
- 引数の個数はファンクションによって異なる(0個のものもある)
- 引数には、列名・リテラル・式を指定できる
- 戻り値のデータ型はファンクションによって異なる
使用できる箇所
- SELECT句のリスト
- WHERE句・HAVING句などの条件式
単一行ファンクションとは
問い合わせ対象の表の各行1件に対して1つの結果を返すファンクションです。グループ全体をまとめて集計する「グループファンクション」とは区別されます。
ファンクション(関数)の分類
①文字ファンクション(文字関数)
引数は文字列型とし、文字列型または数値型を返す関数
②数値ファンクション(数値関数)
引数は数値型とし、数値型を返す関数
③日付ファンクション(日付関数)
引数は日付型とし、日付型または数値型を返す関数
④変換ファンクション(変換関数)
引数の値を別のデータ型に変換する(第5章で確認)
⑤汎用ファンクション(汎用関数)
引数は任意のデータ型とし、NULL値に関する処理を行う(第5章で確認)
文字ファンクション
大文字・小文字の変換
| ファンクション | 構文 | 戻り値 |
|---|---|---|
UPPER |
UPPER(string) |
文字列をすべて大文字に変換 |
LOWER |
LOWER(string) |
文字列をすべて小文字に変換 |
INITCAP |
INITCAP(string) |
単語の先頭のみ大文字、以降を小文字に変換 |
SELECT UPPER('hello oracle') FROM DUAL; -- HELLO ORACLE
SELECT LOWER('HELLO ORACLE') FROM DUAL; -- hello oracle
SELECT INITCAP('hello oracle') FROM DUAL; -- Hello Oracle
🔑
UPPER/LOWERは WHERE句でも使えます。文字列の大文字・小文字を区別しない検索をしたいときに便利です。
-- 大文字・小文字を区別しない検索
SELECT * FROM test_emp_func
WHERE UPPER(last_name) = UPPER('king');
動作確認
■テストデータ
DROP TABLE test_emp_func PURGE;
CREATE TABLE test_emp_func (
employee_id NUMBER(6) PRIMARY KEY,
last_name VARCHAR2(30)
);
INSERT INTO test_emp_func (employee_id, last_name) VALUES (1, 'King');
INSERT INTO test_emp_func (employee_id, last_name) VALUES (2, 'KING');
INSERT INTO test_emp_func (employee_id, last_name) VALUES (3, 'king');
INSERT INTO test_emp_func (employee_id, last_name) VALUES (4, 'Smith');
COMMIT;
CONCAT — 文字列の結合
CONCAT(string1, string2)
2つの文字列を結合して返します。|| 演算子と同じ結果ですが、引数は2つまでです。
SELECT CONCAT('Hello', ' Oracle') FROM DUAL; -- Hello Oracle
-- 3つ以上結合したい場合は || を使うかネストする
SELECT CONCAT(CONCAT('A', 'B'), 'C') FROM DUAL; -- ABC
SUBSTR — 文字列の抜き出し
SUBSTR(string, n [, length])
-
n文字目からlength文字分を抜き出す -
lengthを省略すると、n文字目から末尾まで返す -
nが負の数の場合、末尾から数えた位置を起点にする
SELECT SUBSTR('ABCDEFG', 3) FROM DUAL; -- CDEFG(3文字目から末尾まで)
SELECT SUBSTR('ABCDEFG', 3, 4) FROM DUAL; -- CDEF(3文字目から4文字)
SELECT SUBSTR('ABCDEFG', -3) FROM DUAL; -- EFG(末尾から3番目から末尾まで)
SELECT SUBSTR('ABCDEFG', -3, 2) FROM DUAL; -- EF(末尾から3番目から2文字)
🔑 先頭文字は位置番号 1 です(0始まりではない)。
LPAD / RPAD — 文字埋め込み(桁揃え)
LPAD(string, length [, padding]) -- 左側を埋める(右寄せ)
RPAD(string, length [, padding]) -- 右側を埋める(左寄せ)
-
stringを全体length文字になるようpaddingで埋める -
paddingを省略すると空白で埋める -
stringが既にlength以上の長さの場合、length文字に切り捨てられる
SELECT LPAD('Oracle', 10) FROM DUAL; -- ' Oracle'
SELECT LPAD('Oracle', 10, '*') FROM DUAL; -- '****Oracle'
SELECT RPAD('Oracle', 10, '-') FROM DUAL; -- 'Oracle----'
REPLACE — 文字列の置換
REPLACE(string, search [, replace])
-
stringの中に出現するsearchをreplaceに置き換える -
replaceを省略すると、searchに一致した部分を削除する
SELECT REPLACE('Hello World', 'World', 'Oracle') FROM DUAL; -- Hello Oracle
SELECT REPLACE('AABABAB', 'AB', 'X') FROM DUAL; -- AXX(全件置換)
SELECT REPLACE('Hello World', 'World') FROM DUAL; -- Hello (削除)
TRIM — 前後の文字削除
TRIM([{LEADING | TRAILING | BOTH} [trim_char] FROM] string)
文字列の先頭・末尾から指定した文字を削除します。
| オプション | 効果 |
|---|---|
なし(TRIM(string) だけ) |
前後の空白を削除(BOTHと同じ) |
LEADING |
先頭の連続した trim_char を削除 |
TRAILING |
末尾の連続した trim_char を削除 |
BOTH |
先頭と末尾の両方の連続した trim_char を削除(デフォルト) |
trim_char を省略 |
空白文字を対象にする(全角スペースは対象外) |
SELECT TRIM(' Hello ') FROM DUAL; -- 'Hello'(前後の空白削除)
SELECT TRIM('a' FROM 'aaHelloaa') FROM DUAL; -- 'Hello'
SELECT TRIM(LEADING 'a' FROM 'aaABaa') FROM DUAL; -- 'ABaa'(先頭のみ)
SELECT TRIM(TRAILING 'a' FROM 'aaABaa') FROM DUAL; -- 'aaAB'(末尾のみ)
SELECT TRIM(BOTH 'a' FROM 'aaABaa') FROM DUAL; -- 'AB'(前後)
⚠️
trim_charに指定できるのは 1文字のみです。2文字以上を指定すると ORA-30001 エラーになります。
数値を返す文字ファンクション
LENGTH — 文字数を取得
LENGTH(string)
文字列の文字数を返します。
SELECT LENGTH('Hello') FROM DUAL; -- 5
SELECT LENGTH('オラクル') FROM DUAL; -- 4(全角も1文字でカウント)
SELECT LENGTH(NULL) FROM DUAL; -- NULL
-
stringの中でsearchがn回目に出現する位置を返す - 見つからない場合は
0を返す -
pos・nを省略するとそれぞれ1として扱う -
posが負の場合、末尾から数えた位置を起点に逆方向(文頭方向)に検索する
SELECT INSTR('ORACLE DATABASE', 'A') FROM DUAL; -- 3(最初のA)
SELECT INSTR('ORACLE DATABASE', 'A', 1, 2) FROM DUAL; -- 9(2番目のA)
SELECT INSTR('ORACLE DATABASE', 'A', 5) FROM DUAL; -- 9(5文字目以降で最初のA)
SELECT INSTR('ORACLE DATABASE', 'Z') FROM DUAL; -- 0(見つからない)
🔑 大文字・小文字は区別されます。
INSTR('Oracle', 'o')は0を返します。
数値ファンクション
ROUND — 四捨五入
ROUND(n [, int])
-
int桁で四捨五入する -
intが正 → 小数点以下int桁に丸める -
intが負 → 小数点の左側int桁で丸める -
intを省略 →0として扱い、整数に丸める
| 式 | 結果 |
|---|---|
ROUND(45.678, 2) |
45.68 |
ROUND(45.678, 1) |
45.7 |
ROUND(45.678) |
46 |
ROUND(45.678, -1) |
50 |
ROUND(45.678, -2) |
0 |
TRUNC — 切り捨て
TRUNC(n [, int])
-
int桁で切り捨てる(四捨五入せず、常に切り捨て) - 引数の意味は
ROUNDと同じ
| 式 | 結果 |
|---|---|
TRUNC(45.678, 2) |
45.67 |
TRUNC(45.678, 1) |
45.6 |
TRUNC(45.678) |
45 |
TRUNC(45.678, -1) |
40 |
TRUNC(45.678, -2) |
0 |
🔑 試験ポイント:ROUND と TRUNC の違い
ROUND(45.678, 1)→45.7(四捨五入)TRUNC(45.678, 1)→45.6(切り捨て)
MOD — 余り
MOD(n, div)
-
nをdivで割った余りを返す - 余りの符号は第1引数(
n)の符号に合わせる
| 式 | 結果 |
|---|---|
MOD(5, 3) |
2 |
MOD(15, 3) |
0 |
MOD(5, 10) |
5 |
MOD(-5, 3) |
-2 |
MOD(5, -3) |
2 |
MOD(-5, -3) |
-2 |
POWER — 累乗
POWER(n, m)
-
nのm乗を返す
| 式 | 結果 |
|---|---|
POWER(5, 5) |
3125 |
POWER(0, 5) |
0 |
POWER(5, 0) |
1 |
POWER(-2, 3) |
-8 |
POWER(2, -3) |
0.125 |
日時ファンクション
日時の算術演算
日時データには直接、算術演算子を使えます。
| 式 | 戻り値の型 | 意味 |
|---|---|---|
日時 + 数値 |
日時型 |
数値 日後の日時 |
日時 - 数値 |
日時型 |
数値 日前の日時 |
日時 - 日時 |
数値型 | 2つの日時の差(日数) |
日時 + 日時 |
— | ❌ エラー(加算はできない) |
- 数値
1は1日に相当する - 整数以外(例:
0.5)も使用可能(0.5 = 12時間)
SELECT SYSDATE + 7 FROM DUAL; -- 7日後
SELECT SYSDATE - 3 FROM DUAL; -- 3日前
SELECT SYSDATE - DATE '2024-01-01' FROM DUAL; -- 今日から2024/1/1までの日数(数値)
SYSDATE — 現在の日時を取得
SYSDATE
- データベースサーバーのOSの現在日時を返す(引数不要)
- 戻り値:DATE型(年月日・時分秒)
SELECT SYSDATE FROM DUAL;
-
dtのnか月後の日時を返す -
nが負ならnか月前を返す - 戻り値:DATE型
SELECT ADD_MONTHS(SYSDATE, 3) FROM DUAL; -- 3か月後
SELECT ADD_MONTHS(SYSDATE, -1) FROM DUAL; -- 1か月前
💡 月末の日付に ADD_MONTHS を使うと、結果も月末になります。例:
ADD_MONTHS(DATE '2026-01-31', 1)→2026-02-28
MONTHS_BETWEEN — 2つの日時の月数差
MONTHS_BETWEEN(dt1, dt2)
-
dt1 - dt2の月数を返す - 戻り値:数値型
-
dt1がdt2より後なら正の値、前なら負の値 - 両方が月末日、または同じ日付なら整数を返す
- それ以外は小数を含む(端数は1か月を31日換算で計算)
SELECT MONTHS_BETWEEN(DATE '2026-03-01', DATE '2026-01-01') FROM DUAL; -- 2
SELECT MONTHS_BETWEEN(DATE '2026-01-01', DATE '2026-03-01') FROM DUAL; -- -2
SELECT MONTHS_BETWEEN(DATE '2026-03-15', DATE '2026-01-01') FROM DUAL; -- 非整数
NEXT_DAY — 指定曜日の直後の日付
NEXT_DAY(dt, day_string)
NEXT_DAY(dt, day_number)
-
dtより後の、最初のday_string(またはday_number)の曜日の日付を返す - 曜日名は
NLS_DATE_LANGUAGEの設定に合わせた言語で指定する - 曜日番号は
NLS_TERRITORYに依存し、日曜日が1、土曜日が7
| 環境 | 月曜日の指定方法 |
|---|---|
| 日本語環境 |
'月' または '月曜日'
|
| 英語環境 |
'MON' または 'MONDAY'
|
-- 日本語環境:次の月曜日
SELECT NEXT_DAY(SYSDATE, '月') FROM DUAL;
-- 英語環境:次の月曜日
SELECT NEXT_DAY(SYSDATE, 'MON') FROM DUAL;
-- 曜日番号で指定(日曜=1、月曜=2)
SELECT NEXT_DAY(SYSDATE, 2) FROM DUAL;
LAST_DAY — 月末日を取得
LAST_DAY(dt)
-
dtが属する月の最終日を返す - 戻り値:DATE型
SELECT LAST_DAY(SYSDATE) FROM DUAL; -- 今月の末日
SELECT LAST_DAY(DATE '2026-02-01') FROM DUAL; -- 2026-02-28
SELECT LAST_DAY(DATE '2024-02-01') FROM DUAL; -- 2024-02-29(うるう年)
ROUND (日時) — 日時の丸め
ROUND(dt [, 'format'])
- 書式モデル
formatに従って日時を丸める -
formatを省略するとデフォルトの'DD'(日単位)で丸める - 戻り値:DATE型
| format | 丸めの基準 |
|---|---|
'DD'(デフォルト) |
時間が 00:00:00〜11:59:59 → 当日0時、12:00:00〜23:59:59 → 翌日0時 |
'MM' |
日が 1〜15 → 当月1日、16〜末日 → 翌月1日 |
'YYYY' / 'RR' / 'YY'
|
月が 1〜6 → 当年1月1日、7〜12 → 翌年1月1日 |
SELECT ROUND(TO_DATE('2026-03-16 14:00:00','YYYY-MM-DD HH24:MI:SS'), 'DD')
FROM DUAL; -- 2026-03-17(14時なので翌日)
SELECT ROUND(TO_DATE('2026-03-16', 'YYYY-MM-DD'), 'MM')
FROM DUAL; -- 2026-04-01(16日なので翌月1日)
TRUNC (日時) — 日時の切り捨て
TRUNC(dt [, 'format'])
- 書式モデル
formatに従って日時を切り捨てる -
formatを省略するとデフォルトの'DD'(日単位)で切り捨て - 戻り値:DATE型
| format | 切り捨て後の値 |
|---|---|
'DD'(デフォルト) |
時刻部分をゼロにする(00:00:00) |
'MM' |
当月1日の 00:00:00 |
'YYYY' / 'RR' / 'YY'
|
当年1月1日の 00:00:00 |
SELECT TRUNC(SYSDATE) FROM DUAL; -- 今日の 00:00:00
SELECT TRUNC(SYSDATE, 'MM') FROM DUAL; -- 当月1日
SELECT TRUNC(DATE '2026-03-28', 'YYYY') FROM DUAL; -- 2026-01-01
🔑 試験ポイント:ROUND と TRUNC(日時)の違い
ROUND('MM')→ 16日以降なら翌月1日TRUNC('MM')→ 常に当月1日(日付に関わらず切り捨て)
ファンクションまとめ
文字ファンクション一覧
| ファンクション | 構文 | 戻り値の型 |
|---|---|---|
UPPER |
UPPER(str) |
VARCHAR2 |
LOWER |
LOWER(str) |
VARCHAR2 |
INITCAP |
INITCAP(str) |
VARCHAR2 |
CONCAT |
CONCAT(s1, s2) |
VARCHAR2 |
SUBSTR |
SUBSTR(str, n [,len]) |
VARCHAR2 |
LPAD |
LPAD(str, len [,pad]) |
VARCHAR2 |
RPAD |
RPAD(str, len [,pad]) |
VARCHAR2 |
REPLACE |
REPLACE(str, search [,rep]) |
VARCHAR2 |
TRIM |
TRIM([{LEADING|TRAILING|BOTH} [char] FROM] str) |
VARCHAR2 |
LENGTH |
LENGTH(str) |
NUMBER |
INSTR |
INSTR(str, search [,pos [,n]]) |
NUMBER |
数値ファンクション一覧
| ファンクション | 構文 | 概要 |
|---|---|---|
ROUND |
ROUND(n [,int]) |
四捨五入 |
TRUNC |
TRUNC(n [,int]) |
切り捨て |
MOD |
MOD(n, div) |
余り(符号は第1引数に合わせる) |
POWER |
POWER(n, m) |
n の m 乗 |
日時ファンクション一覧
| ファンクション | 構文 | 戻り値の型 |
|---|---|---|
SYSDATE |
SYSDATE |
DATE |
ADD_MONTHS |
ADD_MONTHS(dt, n) |
DATE |
MONTHS_BETWEEN |
MONTHS_BETWEEN(dt1, dt2) |
NUMBER |
NEXT_DAY |
NEXT_DAY(dt, day) |
DATE |
LAST_DAY |
LAST_DAY(dt) |
DATE |
ROUND |
ROUND(dt [,'format']) |
DATE |
TRUNC |
TRUNC(dt [,'format']) |
DATE |
参考
- Oracle Docs:ROUNDおよびTRUNC日付ファンクション
- Oracle Docs:SUBSTR
- Oracle Docs:TRUNC (日付)
- shift-the-oracle:LPAD
- shift-the-oracle:MONTHS_BETWEEN












































