「データベース」タグアーカイブ

SQL:合計や平均を算出する方法

SQLで合計を求めるにはSUM関数、平均を求めるにはAVG関数を使用します。

DBMS毎の使用可否

関数\DBMSMySQLPostgreSQLSQL ServerOracle
SUM
AVG
 

サンプルテーブル

「GOODS」テーブル

合計を求める実行例

SUM関数を使用したクエリー(SQL)例

  • 以下の例ではGOODSテーブルのPRICE項目の合計値を求めています。

実行結果

平均を求める例

AVG関数を使用したクエリー(SQL)例

  • 以下の例ではGOODSテーブルのPRICE項目の平均値を求めています。

実行結果

SQL:副問合せの結果をALL句で比較して取得する方法

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

サンプルテーブル

  • 「GOODS」テーブル
  • 「GOODS_TYPE」テーブル

ALL句を利用したクエリー(SQL)例

  • 以下の例ではまず副問合せでGOODS_CODEテーブルからGOODS_CODEが101と301のデータを取得し、ALL句でGOODSテーブルのGOODS_CODEが101と301以外のデータを取得しています。

実行結果

Oracle:DESCRIBEコマンドでテーブル(表)構造を確認する方法

SQL PlusやSQL Developerに用意されている「DESCRIBE」コマンドを使用することでテーブル構造を確認することが出来ます。

DESCRIBEコマンドはDESCと省略することも出来ます。

SQL PlusでのDESCRIBEコマンド実行例

  • 「DESCRIBE テーブル名」でテーブル構造が確認できます。

SQL PlusでのDESCコマンド実行例

  • DESCでもDESCRIBEと同じ結果を取得できます。

SQL:文字列や数値項目へ埋め込み文字を挿入して桁数を揃える方法

SQLでゼロ埋めスペース埋めして桁数を揃えたい場合にはLPAD関数やRPAD関数を使用することで取得可能となります。DBMSによっては使用出来ないものもあります。

関数\DBMSMySQLPostgreSQLSQL ServerOracle
LPAD
RPAD
 

書式は「LPAD(列名,バイト数,’埋め込み文字’)」、「RPAD(列名,バイト数,’埋め込み文字’)」で指定します。第三引数の埋め込み文字を省略すると半角スペースが埋め込まれます。

サンプルではOracleでの使用例となります。

サンプルテーブル

  • 「GOODS」テーブル

LPAD関数の使用例1

  • 項目「GOODS_CODE」を10桁でゼロ埋めするSQL(クエリー)
  • 実行結果

LPAD関数の使用例2

  • 項目「GOODS_CODE」を10桁で全角「*」埋めするSQL(クエリー)
  • 実行結果
    以下のように埋め込み文字へ全角文字を指定すると1文字=2バイト扱いで埋め込まれます。

RPAD関数の使用例1

  • 項目「GOODS_CODE」を10桁でゼロ埋めするSQL(クエリー)
  • 実行結果

RPAD関数の使用例2

  • 項目「GOODS_CODE」を10桁で全角「*」埋めするSQL(クエリー)
  • 実行結果
    RPADでも以下のように埋め込み文字へ全角文字を指定すると1文字=2バイト扱いで埋め込まれます。

SQL:WHERE句内で「(+)」を指定する意味

SQLを見てるとたまにWHERE句内で「(+)」と記載されているのを見かけることがあります。

この「(+)」はOracle独自で記載が可能となる外部結合演算子といって、「g.GOODS_CODE = gt.GOODS_CODE(+)」のように指定するとLEFT OUTER JOINと同じ結果を取得することが出来ます。

サンプルテーブル

  • 「GOODS」テーブル
  • 「GOODS_TYPE」テーブル

外部結合演算子を利用したクエリー(SQL)例

通常の左外部結合でのクエリー(SQL)例

実行結果

外部結合演算子、左外部結合どちらも同じ結果となります。

補足

  • 「(+)」演算子の歴史的背景
    Oracle の古いバージョンからサポートされていた外部結合の書き方で、ANSI SQL 標準が普及する以前によく使われていました。ANSI 標準(LEFT JOIN / RIGHT JOIN / FULL OUTER JOIN)が登場して以降は、可読性・移植性の観点から推奨されないことが多いです。

  • 制限・注意点

    1. 可読性・保守性g.GOODS_CODE = gt.GOODS_CODE(+) のような記述は、JOIN の方向やどのテーブルに外部結合をかけているかが分かりにくく、後でクエリを読む人が迷いやすいです。

    2. 複雑な結合:複数テーブルを結合する場合、どこに (+) を付けるか、また付け方によって結果が変わるため、注意深く設計する必要があります。

    3. NULL の扱い:外部結合によって NULL が返る行が含まれますが、条件節で他の条件と組み合わせると意図しない行の除外が起きることがあります(例えば WHERE 節で AND 条件として別の非 NULL 条件を加えると外部結合の意味が薄れる等)。

  • ANSI 標準との違い

    項目 (+) 外部結合演算子 ANSI SQL 外部結合 (LEFT OUTER JOIN 等)
    可読性やや分かりにくい比較的分かりやすい
    移植性Oracle に依存多くの RDBMS でサポートされる
    複雑な JOIN の組み立てエラーや誤解の元になりやすいON 句で明示的に指定できるため制御しやすい
    サポート状況最新 Oracle でも非推奨の方向推奨される方式
     

  • 現代のベストプラクティス

    • 新規開発では ANSI SQL の外部結合構文を使うことを推奨。可読性や他 DBMS への移植性が高いため。

    • 既存システムで (+) を使っているなら、リファクタリングやドキュメント整備を行い、「なぜこの構文になっているか」「どのような影響があるか」を明らかにしておく。

    • テストを用意して、クエリ変更後に結果が同じになることを検証する(特に NULL の扱いや結合の漏れが起きていないか)。

  • 実際の書き換え例

    旧構文を ANSI 標準に書き換えるときの例をもう一つ:

     
    -- 旧構文

    -- 書き換え後(ANSI 標準)

    このように、結合条件を ON に書き出すことで構造が明瞭になります。

  • 互換性・移行のヒント

    • Oracle のバージョンによっては (+) 構文が将来削除される可能性があり、非推奨の警告が出ることもあります。

    • 他の RDBMS(PostgreSQL、MySQL、SQL Serverなど)で同じSQLを使うことを想定するなら、ANSI JOINに統一しておくと移行がスムーズです。

    • クエリのパフォーマンスにも注意。古い構文でも Oracle のオプティマイザが合理化する場合がありますが、可視性や保守性を取る方が長期的には有利。

Oracle:ユーザー作成時に「ORA-65096」エラーが出た場合の原因と対応方法

Oracleのインストール後にSQL*Plusなどでユーザー作成しようとした際、「ORA-65096」エラーが発生した場合の原因と対応方法についてメモしておきます。

「ORA-65096:共通ユーザーまたはロール名が無効です」の原因

  • ルートコンテナにローカルユーザーを作成しようとした場合に発生するエラーとなります。
    ルートコンテナには共有ユーザー(common user) と呼ばれる特殊なユーザーしか作成することはできません。
    Oracle 11gまでと違いOracle 12c以降からは一つのインスタンスには一つのコンテナ・データベース(CDB)と、プラガブル・データベース(PDB)と呼ばれる子DBが存在しています。sysなどのユーザーでログイン直後はコンテナ・データベース(CDB)に接続されている状態となっているため、そのままローカルユーザーを作成しようとしてもエラーが発生してしまうということになります。

「ORA-65096:共通ユーザーまたはロール名が無効です」の対処方法

原因が分かってしまえば対応はシンプルです。接続先がコンテナ・データベース(CDB)であるのがまずいのであればプラガブル・データベース(PDB)に変更してしまえばいいだけです。

  1. まずは「show con_name;」で現在接続されているデータベースを確認します。
  2. 次に「select name, open_mode from v$pdbs;」でPDBの名前と現在のOPEN_MODEを確認します。
  3. PDBの名前が「ORCLPDB」というのがわかったのでデータベースの接続先を「ORCLPDB」へ変更します。
  4. もう一度「show con_name;」を実行して接続先が変更されていることを確認します。
  5. 接続先がPDBへ変更されたのでもう一度ユーザー作成を実行すると正常に実行されます。

 

データベース製品のライセンス一覧

データベース製品のライセンス一覧です。

製品名オープンソース/商用ライセンスデータ
モデル
料金
DB2商用IBMORDBMS1プロセッサ
・461万7000円
2年目から5年目の保守料
・88万700円/年
1プロセッサで5年間運用した場合のコスト
・813万9800円
HiRDB商用日立製作所RDBMS同時接続数ライセンス
・120,000円
1プロセッサ
・1,800,000円
MySQLオープンソースGPL or 商用RDBMS1-4 ソケットサーバー 1台/年(税抜)
・Standard Edition:240,000
・Enterprise Edition:600,000
・Cluster Carrier Grade Edition:1,200,000
5+ ソケット・サーバー/年(税抜)
・Standard Edition:480,000
・Enterprise Edition:1,200,000
・Cluster Carrier Grade Edition:2,400,000
Oracle Database商用オラクルRDBMS
PostgreSQLオープンソースBSDORDBMS無料

Oracle:リカバリとリストアの違い

Oracleデータベースのリカバリとリストアの概念が少し理解しずらかったので整理しておこうと思います。
基本的にはパソコンのOSなどにおけるリカバリ(復旧)/リストア(復元)と言葉的な概念は同じですが、実作業は異なるものだと別物と覚えたほうが良さそうです。

リストアとは

  • 一般的にパソコンのリストアといえばバックアップデータを用いてOSなどのデータを元の状態に戻す(復元)することを指します。
  • Oracleデータベースのリストアとは、バックアップ媒体から元の場所もしくは新しい場所へデータベースを構成する物理ファイルをコピーして復元することを指します。

リカバリとは

  • 一般的にパソコンのリカバリといえばパソコンにインストールされているOSを出荷時の状態に戻す(復旧する)作業のことをいいます。
  • Oracleデータベースのリカバリとは、REDOログファイル(バックアップ取得~現在までのトランザクションの変更情報が保存されています)を使用してバックアップ後に作成されたデータベースへ変更情報を反映してデータを復旧することを指します。

TRUNCATEとDELETEの違い

テーブルのデータを削除する方法として「DELETE」コマンドと「TRUNCATE TABLE」コマンドの2つがあります。
両者を使用する場合、どのような用途で使用するべきか違いについてまとめておきます。

DELETE文

  • DELETEはTABLEのレコードを行単位で削除する事も可能。
  • DELETEはデータ削除のみ実施するだけでで「AUTO_INCREMENT」の値は初期化しません。
  • DELETE後にROLLBACK可能

TRUNCATE文

  • TRUNCATEはTABLEをDROP後にCREATEする為、行単位での削除は不可能。
  • TRUNCATEは「AUTO_INCREMENT」が設定されている場合は値が初期化されます。
  • TRUNCATE後にROLLBACKは不可能。
  • DELETEより高速。

MySQLからMariaDBへ

ちょっとした案件でデータベースというとMySQLをとりあえず使っておこうという人はそれなりにいたかと思いますが、いまはその状況が変わってきています。

MySQLのオリジナルコードの作者のひとりがMySQLのコードをフォークして新しいプロジェクトを立ち上げたからです。
MariaDBという新しいデータベースプロジェクトです。MySQLと互換性も高く機能の取り込みも早いとの話です。
GoogleもMySQLからMariaDBに乗り換えたという話が出てきています。
よく使われるLinuxディストリビューションのひとつであるCentOSの標準環境もMySQLからMariaDBに変わりました。バージョン7からです。
CentOSだけではなくFedoraなどもMariaDBを標準に採用しているということだそうです。このことからもわかるとおりにMySQLからMariaDBへの移行が進んでいます。

CentOSさえもMariaDBを標準で採用したことからもわかるとおりに、この流れは止まらないことでしょう。
もしも乗り換える際は当たり前の話ですがきちんと検証してから使っていきたいですね。