SQLでシステム日付、誕生日を使用して年齢、システム日付~誕生日までの月数、日数を取得するSQLをメモしておきます。
以下はOracleでの実行例となっています。
サンプルテーブル
「BIRTHDAY」テーブル

【Oracle】システム日付と誕生日から年齢、誕生日までの月数、日数を表示する例
クエリー(SQL)例
|
SELECT TO_CHAR(sysdate,'YYYY-MM-DD') "本日の日付", TO_CHAR(b.BIRTHDAY,'YYYY-MM-DD') "誕生日", EXTRACT(YEAR FROM sysdate) - EXTRACT(YEAR FROM b.BIRTHDAY) "年齢", TRUNC(MONTHS_BETWEEN(sysdate,b.BIRTHDAY)) "誕生日までの月数", TRUNC(sysdate - b.BIRTHDAY) "誕生日までの日数" FROM dual, BIRTHDAY b; |
実行結果

UPDATEで他のテーブルと結合(JOIN)した結果に対してのみ更新を実施したい場合、SQL ServerやMySQL、PostgreSQLではUPDATE文内に直接JOIN句を記載可能ですが、Oracleでは副問合せで結合することでJOINした結果に対して更新することが可能となります。
サンプルテーブル
「GOODS」テーブル

「GOODS_TYPE」テーブル

【Oracle】UPDATE文でJOINを使用して更新する例
クエリー(SQL)例
- 以下の例ではGOODS_TYPEテーブルに存在するGOODS_CODEと一致するレコードのみGOODSテーブルのPRICE項目を更新しています。
|
UPDATE GOODS SET PRICE = 5000 WHERE GOODS_CODE = ANY (SELECT g.GOODS_CODE FROM GOODS g INNER JOIN GOODS_TYPE gt ON gt.GOODS_CODE = g.GOODS_CODE) |
実行結果
- 以下の様にGOODS_CODEが一致しているレコードのみ更新されていることが確認できます。

【SQL Server、MySQL、PostgreSQL】UPDATE文でJOINを使用して更新する例
クエリー(SQL)例
- SQL Serverなどでは直接UPDATE文内にJOINを指定可能なので以下のような記載でもエラーにはならず更新されます。
|
UPDATE g SET r.PRICE = 5000; FROM GOODS g INNER JOIN GOODS_TYPE gt ON gt.GOODS_CODE = g.GOODS_CODE |
SQLで合計を求めるにはSUM関数、平均を求めるにはAVG関数を使用します。
DBMS毎の使用可否
関数\DBMS | MySQL | PostgreSQL | SQL Server | Oracle |
SUM | ○ | ○ | ○ | ○ |
AVG | ○ | ○ | ○ | ○ |
サンプルテーブル
「GOODS」テーブル

合計を求める実行例
SUM関数を使用したクエリー(SQL)例
- 以下の例ではGOODSテーブルのPRICE項目の合計値を求めています。
|
SELECT SUM(PRICE) FROM GOODS; |
実行結果

平均を求める例
AVG関数を使用したクエリー(SQL)例
実行結果

ALL句を使用することでWHERE句内に指定した副問合せの結果を比較してデータを抽出する事が可能となります。
サンプルテーブル
- 「GOODS」テーブル

- 「GOODS_TYPE」テーブル

ALL句を利用したクエリー(SQL)例
- 以下の例ではまず副問合せでGOODS_CODEテーブルからGOODS_CODEが101と301のデータを取得し、ALL句でGOODSテーブルのGOODS_CODEが101と301以外のデータを取得しています。
|
SELECT * FROM GOODS WHERE GOODS_CODE <> ALL ( SELECT GOODS_CODE FROM GOODS_TYPE WHERE GOODS_CODE in('101','301') ); |
実行結果

SQLでゼロ埋めスペース埋めして桁数を揃えたい場合にはLPAD関数やRPAD関数を使用することで取得可能となります。DBMSによっては使用出来ないものもあります。
関数\DBMS | MySQL | PostgreSQL | SQL Server | Oracle |
LPAD | ○ | ○ | ✕ | ○ |
RPAD | ○ | ○ | ✕ | ○ |
書式は「LPAD(列名,バイト数,’埋め込み文字’)」、「RPAD(列名,バイト数,’埋め込み文字’)」で指定します。第三引数の埋め込み文字を省略すると半角スペースが埋め込まれます。
サンプルではOracleでの使用例となります。
サンプルテーブル
- 「GOODS」テーブル

LPAD関数の使用例1
- 項目「GOODS_CODE」を10桁でゼロ埋めするSQL(クエリー)
|
SELECT LPAD(g.GOODS_CODE , 10, '0') FROM USER1.GOODS g; |
- 実行結果

LPAD関数の使用例2
- 項目「GOODS_CODE」を10桁で全角「*」埋めするSQL(クエリー)
|
SELECT LPAD(g.NAME , 10, '*') FROM USER1.GOODS g; |
- 実行結果
以下のように埋め込み文字へ全角文字を指定すると1文字=2バイト扱いで埋め込まれます。
RPAD関数の使用例1
- 項目「GOODS_CODE」を10桁でゼロ埋めするSQL(クエリー)
|
SELECT RPAD(g.GOODS_CODE , 10, '0') FROM USER1.GOODS g; |
- 実行結果

RPAD関数の使用例2
- 項目「GOODS_CODE」を10桁で全角「*」埋めするSQL(クエリー)
|
SELECT RPAD(g.NAME , 10, '*') FROM USER1.GOODS g; |
- 実行結果
RPADでも以下のように埋め込み文字へ全角文字を指定すると1文字=2バイト扱いで埋め込まれます。
SQLを見てるとたまにWHERE句内で「(+)」と記載されているのを見かけることがあります。
この「(+)」はOracle独自で記載が可能となる外部結合演算子といって、「g.GOODS_CODE = gt.GOODS_CODE(+)」のように指定するとLEFT OUTER JOINと同じ結果を取得することが出来ます。
サンプルテーブル
- 「GOODS」テーブル

- 「GOODS_TYPE」テーブル

外部結合演算子を利用したクエリー(SQL)例
|
SELECT g.name, gt.type_name FROM USER1.GOODS g, USER1.GOODS_TYPE gt WHERE g.GOODS_CODE = gt.GOODS_CODE(+); |
通常の左外部結合でのクエリー(SQL)例
|
SELECT g.name, gt.type_name FROM USER1.GOODS g LEFT OUTER JOIN USER1.GOODS_TYPE gt ON g.GOODS_CODE = gt.GOODS_CODE; |
実行結果
外部結合演算子、左外部結合どちらも同じ結果となります。

補足
-
「(+)」演算子の歴史的背景
Oracle の古いバージョンからサポートされていた外部結合の書き方で、ANSI SQL 標準が普及する以前によく使われていました。ANSI 標準(LEFT JOIN
/ RIGHT JOIN
/ FULL OUTER JOIN
)が登場して以降は、可読性・移植性の観点から推奨されないことが多いです。
-
制限・注意点
-
可読性・保守性:g.GOODS_CODE = gt.GOODS_CODE(+)
のような記述は、JOIN の方向やどのテーブルに外部結合をかけているかが分かりにくく、後でクエリを読む人が迷いやすいです。
-
複雑な結合:複数テーブルを結合する場合、どこに (+)
を付けるか、また付け方によって結果が変わるため、注意深く設計する必要があります。
-
NULL の扱い:外部結合によって NULL が返る行が含まれますが、条件節で他の条件と組み合わせると意図しない行の除外が起きることがあります(例えば WHERE 節で AND
条件として別の非 NULL 条件を加えると外部結合の意味が薄れる等)。
-
ANSI 標準との違い
項目 | (+) 外部結合演算子 | ANSI SQL 外部結合 (LEFT OUTER JOIN 等) |
可読性 | やや分かりにくい | 比較的分かりやすい |
移植性 | Oracle に依存 | 多くの RDBMS でサポートされる |
複雑な JOIN の組み立て | エラーや誤解の元になりやすい | ON 句で明示的に指定できるため制御しやすい |
サポート状況 | 最新 Oracle でも非推奨の方向 | 推奨される方式 |
-
現代のベストプラクティス
-
新規開発では ANSI SQL の外部結合構文を使うことを推奨。可読性や他 DBMS への移植性が高いため。
-
既存システムで (+)
を使っているなら、リファクタリングやドキュメント整備を行い、「なぜこの構文になっているか」「どのような影響があるか」を明らかにしておく。
-
テストを用意して、クエリ変更後に結果が同じになることを検証する(特に NULL の扱いや結合の漏れが起きていないか)。
-
実際の書き換え例
旧構文を ANSI 標準に書き換えるときの例をもう一つ:
-
互換性・移行のヒント
-
Oracle のバージョンによっては (+)
構文が将来削除される可能性があり、非推奨の警告が出ることもあります。
-
他の RDBMS(PostgreSQL、MySQL、SQL Serverなど)で同じSQLを使うことを想定するなら、ANSI JOINに統一しておくと移行がスムーズです。
-
クエリのパフォーマンスにも注意。古い構文でも Oracle のオプティマイザが合理化する場合がありますが、可視性や保守性を取る方が長期的には有利。
trimは通常、文字列の前後の半角スペースを削除して取得する場合に使用する場合が多いと思いますが、引数へLEADING、TRAILING、BOTHを指定することで任意の文字や文字列を削除して取得することが出来ます。
サンプルテーブル
- 「goods」テーブル

TRIMに引数「LEADING」を指定した場合
TRIMに引数「LEADING」を指定することで文字列の先頭にある任意の文字や文字列を削除することが出来ます。
- クエリー(SQL)例
|
SELECT TRIM(LEADING '商品' From name) FROM goods ORDER BY id; |
- 実行結果

TRIMに引数「TRAILING」を指定した場合
TRIMに引数「TRAILING」を指定することで文字列の末尾にある任意の文字や文字列を削除することが出来ます。
- クエリー(SQL)例
|
SELECT TRIM(TRAILING 'A' From name) FROM goods ORDER BY id; |
- 実行結果

TRIMに引数「BOTH」を指定した場合
TRIMに引数「BOTH」を指定することで文字列の先頭と末尾にある任意の文字や文字列を削除することが出来ます。
- クエリー(SQL)例
|
SELECT TRIM(BOTH 'A' From name) FROM goods ORDER BY id; |
- 実行結果

SQLで大文字⇒小文字に変換する場合はLCASE関数 or LOWER関数、小文字⇒大文字へ変換するにはUCASE関数 or UPPER関数を使用します。DBMS毎で使用出来る関数が異なるので整理しておきます。
サンプルではPostgreSQLでの使用例となります。
関数\DBMS | MySQL | PostgreSQL | SQL Server | Oracle |
UCASE
※小文字 ⇒ 大文字 | ○ | ✕ | ✕ | ✕ |
UPPER
※小文字 ⇒ 大文字 | ✕ | ○ | ○ | ○ |
LCASE
※大文字 ⇒ 小文字 | ○ | ✕ | ✕ | ✕ |
LOWER
※大文字 ⇒ 小文字 | ✕ | ○ | ○ | ○ |
サンプルテーブル
- 「goods」テーブル

UPPER関数(小文字 ⇒ 大文字へ変換)の使用例
- クエリー(SQL)例
|
SELECT UPPER(name) FROM goods ORDER BY id; |
- 実行結果

LOWER関数(大文字 ⇒ 小文字へ変換)の使用例
- クエリー(SQL)例
|
SELECT LOWER(name) FROM goods ORDER BY id; |
- 実行結果

SQLで一部の文字列を取得するにはSUBSTR関数やLEFT関数、RIGHT関数を使用することで可能となります。DBMS毎に利用できる関数に違いがありOracleではLEFT関数、RIGHT関数は使用出来ません。
関数\DBMS | MySQL | PostgreSQL | SQL Server | Oracle |
SUBSTR or SUBSTRING | ○ | ○ | ○ | ○ |
LEFT | ○ | ○ | ○ | ✕ |
RIGHT | ○ | ○ | ○ | ✕ |
サンプルテーブル
- 「goods」テーブル

SUBSTR関数の使用例
LEFT関数の使用例
RIGHT関数の使用例
「駑馬十駕」を信念に IT系情報を中心に調べた事をコツコツ綴っています。