Oracleデータベースの集計ファンクション(SUM、AVG、MAX、MIN、COUNTなど)は、データ分析やレポート作成に欠かせない重要な機能です。本記事では、初心者の方にもわかりやすいように以下の2点について解説します。
- 集計ファンクションにおけるNULLの扱い
- DISTINCTを使用した集計処理
この記事では、特定の学習用に作成した**EMP_TEST
テーブル**を使用します。このテーブルには従業員情報が格納されており、以下にCREATE文とINSERT文を記載します。
リンク
リンク
リンク
使用するテーブル
以下のSQLを実行して、EMP_TEST
テーブルを作成しデータを挿入してください。
-- テーブル作成
CREATE TABLE EMP_TEST (
EMP_ID NUMBER PRIMARY KEY, -- 従業員ID
NAME VARCHAR2(50), -- 名前
JOB VARCHAR2(50), -- 職種
SAL NUMBER, -- 給与
DEPT_ID NUMBER, -- 部署ID
BONUS NUMBER -- ボーナス
);
-- データ挿入
INSERT INTO EMP_TEST VALUES (1, 'Alice', 'Manager', 3000, 10, NULL);
INSERT INTO EMP_TEST VALUES (2, 'Bob', 'Clerk', NULL, 20, NULL);
INSERT INTO EMP_TEST VALUES (3, 'Charlie', 'Analyst', 4000, 10, 500);
INSERT INTO EMP_TEST VALUES (4, 'David', 'Clerk', 2500, 30, 300);
INSERT INTO EMP_TEST VALUES (5, 'Emma', 'Salesman', 2000, 30, 200);
INSERT INTO EMP_TEST VALUES (6, 'Frank', 'Manager', 3000, 20, NULL);
INSERT INTO EMP_TEST VALUES (7, 'Grace', 'Analyst', 4000, 20, 500);
INSERT INTO EMP_TEST VALUES (8, 'Helen', 'Salesman', 2000, 30, 200);
INSERT INTO EMP_TEST VALUES (9, 'Ian', 'Clerk', 2500, 20, NULL);
INSERT INTO EMP_TEST VALUES (10, 'Jane', 'Clerk', NULL, 10, NULL);
COMMIT;
1. 集計ファンクションにおけるNULLの扱い
集計ファンクションのNULLの基本ルール
Oracleの集計ファンクションでは、基本的にNULL値を無視して計算します。ただし、COUNT(*)
は例外で、NULL値を含むすべての行をカウントします。
以下の表に主要な集計ファンクションとNULLの扱いをまとめました:
ファンクション | NULLの扱い |
---|---|
SUM, AVG | 無視 |
MAX, MIN | 無視 |
COUNT(列名) | 無視 |
COUNT(*) | カウントする |
実例:EMP_TESTテーブルを使用
-- SAL列(従業員の給与)の合計を計算
SELECT SUM(SAL) AS TOTAL_SAL FROM EMP_TEST;
-- 結果
TOTAL_SAL
---------
23000
-- COUNT関数のNULLの扱い
SELECT COUNT(SAL) AS COUNT_SAL, COUNT(*) AS COUNT_ALL FROM EMP_TEST;
-- 結果
COUNT_SAL | COUNT_ALL
----------+----------
8 | 10
解説:
SUM(SAL)
は、SAL列のNULLを無視して合計を計算します。COUNT(SAL)
は、SAL列の値がNULLでない行をカウントします。COUNT(*)
は、NULLを含むすべての行をカウントします。
2. DISTINCTを使用した集計処理
DISTINCTの概要
DISTINCTキーワードを使用すると、指定列の重複する値を除外して計算を行います。これにより、重複値を考慮せずに正確な集計が可能になります。
実例:SAL列の合計でDISTINCTを使用
-- SAL列の合計を通常通り計算
SELECT SUM(SAL) AS TOTAL_SAL FROM EMP_TEST;
-- 結果
TOTAL_SAL
---------
23000
-- SAL列にDISTINCTを使用して合計を計算
SELECT SUM(DISTINCT SAL) AS TOTAL_DISTINCT_SAL FROM EMP_TEST;
-- 結果
TOTAL_DISTINCT_SAL
-------------------
15500
解説:
SUM(SAL)
では、重複する給与額もすべて合計に含まれます。SUM(DISTINCT SAL)
では、重複する給与額を除外した結果が表示されます。
COUNT関数とDISTINCT
DISTINCTはCOUNT
関数と組み合わせることで、一意の値の数をカウントできます。
-- DEPT_ID列の一意の値の数をカウント
SELECT COUNT(DISTINCT DEPT_ID) AS UNIQUE_DEPT_COUNT FROM EMP_TEST;
-- 結果
UNIQUE_DEPT_COUNT
-----------------
3
COUNT(DISTINCT DEPT_ID)
では、DEPT_ID
列の値の中から重複を除外してカウントしています。
3. 視覚的に理解する:NULLとDISTINCTの違い
以下は、SAL列の元データをもとに、NULLやDISTINCTの扱いを視覚化した例です。
SAL列の元データ
3000, NULL, 4000, 2500, 2000, 3000, 4000, 2000, 2500, NULL
NULLを無視した場合(SUM, AVGなど)
SAL列からNULLを無視
--> すべての値を合計: 23000
DISTINCTを適用した場合
重複値を除外
元データ: 3000, NULL, 4000, 2500, 2000, 3000, 4000, 2000, 2500, NULL
DISTINCT適用後: 3000, 4000, 2500, 2000
--> 合計: 15500
4. 注意点とベストプラクティス
- NULL値の影響を理解する: 集計ファンクションはNULLを無視するため、NULLを含む列の集計を行う際には、結果が意図通りであるかを確認しましょう。
- DISTINCTを使う際のパフォーマンス: DISTINCTは重複排除の処理が加わるため、大量データに適用するとパフォーマンスに影響が出る場合があります。
- COUNT(*)とCOUNT(列名)の違い: COUNT(*)はNULLを含むすべての行をカウントしますが、COUNT(列名)はNULLを無視します。意図した動作を確認して使用しましょう。
まとめ
- 集計ファンクション(SUM、AVG、MAX、MIN、COUNT)は、基本的にNULLを無視して計算します。ただし、
COUNT(*)
はNULLを含むすべての行をカウントします。 - DISTINCTを使用すると、指定列の重複を除外して集計が可能です。
- NULL値やDISTINCTの扱いを正確に理解することで、より効率的なデータ分析が可能になります。
この記事で紹介したEMP_TEST
テーブルを使いながら、SQLを実際に実行して理解を深めてください!
[参考]
Oracle Database SQL言語リファレンス 19c
コメント