Oracle SQL 関数 : COUNT : データの存在する行数を計数

 numberRet := COUNT( [ * , [ALL , DISTINCT] <expr> ] [ OVER <分析句> ] )

COUNTは集計関数、または分析関数として使用します。
COUNT(*)は行の項目にNULLがあっても、また重複行があっても全ての行の数を返します。
<expr>が指定された場合は、NULLの項目は計数されません。また、DISTINCT指定の場合は重複行は計数されません。

COUNTの説明をする為に、以下のTT_売上明細の表を例にします。

SQL> SELECT * FROM TT_売上明細 ORDER BY 売上番号,明細番号;

  売上番号   明細番号 商品コード   売上数量 備考                                       売上単価
---------- ---------- ---------- ---------- ---------------------------------------- ----------
         1          1          1          2 *****
         1          2          4          1 NOTE-1010                                    188000
         2          1          2          1 PC-9002                                      120000
         2          2          5          2 NOTE-1020                                    200000
         2          3         11          1 HUB-A001                                      40000
         3          1          3          3 PC-9003                                      190000
         4          1          6          1 NOTE-1030                                    220000
         4          2          7          2 PRT-3001                                      88000
         5          1          8          3 PRT-4001                                     180000
         5          2          9          2 CRT-1001                                      78000
         6          1          8          1 PRT-4001                                     180000
         6          2          9          1 CRT-1001                                      78000
         6          3         10          2 CRT-2001                                      98000
         8          1          8          3 PRT-4001                                     180000
         8          2          9          1 CRT-1001                                      78000
         9          1          7          2 PRT-3001                                      88000
         9          2          9          1 CRT-1001                                      78000

17行が選択されました。

以下に、COUNT(*)COUNT(<expr>)、及びCOUNT(DISTINCT <expr>)の例を示します。

SQL> SELECT COUNT(*),COUNT(商品コード),COUNT(DISTINCT 商品コード) FROM TT_売上明細;

  COUNT(*) COUNT(商品コード) COUNT(DISTINCT商品コード)
---------- ----------------- -------------------------
        17                17                        11

確かに、DISTINCT指定は商品コードの重複分を除き、TT_売上明細での商品コードの使用種類を表しています。
さらに、COUNTとGROUP BY句の使用例を以下に示します。各商品毎の売上件数を計数しています。

SQL> SELECT 商品コード,COUNT(商品コード) FROM TT_売上明細
  2  GROUP BY 商品コード
  3  ORDER BY 商品コード;

商品コード COUNT(商品コード)
---------- -----------------
         1                 1
         2                 1
         3                 1
         4                 1
         5                 1
         6                 1
         7                 2
         8                 3
         9                 4
        10                 1
        11                 1

11行が選択されました。

分析の例として以下に示します。
ORDER BY句で計数の対象となるカラムを指定し、RANGE指定で現在値からみて前後の値の範囲を指定します。
PRECEDINGからFOLLOWINGまでの範囲に入るデータの件数を計数することになります。
以下の例でいえば、COUNT1のカラムは売上数量が現在値より1個少なくかつ現在値までの明細件数を計数し、COUNT2のカラムは現在の商品コードと同じものが存在する明細件数を計数します。

SQL> SELECT
  2   売上番号,明細番号,商品コード,売上数量
  3  ,COUNT(*) OVER (ORDER BY 売上数量
  4    RANGE BETWEEN 1 PRECEDING AND 0 FOLLOWING) AS COUNT1
  5  ,COUNT(*) OVER (ORDER BY 商品コード
  6    RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING) AS COUNT2
  7  FROM TT_売上明細
  8  ORDER BY 売上番号,明細番号;

  売上番号   明細番号 商品コード   売上数量     COUNT1     COUNT2
---------- ---------- ---------- ---------- ---------- ----------
         1          1          1          2         14          1
         2          1          2          1          8          1
         3          1          3          3          9          1
         1          2          4          1          8          1
         2          2          5          2         14          1
         4          1          6          1          8          1
         9          1          7          2         14          2
         4          2          7          2         14          2
         6          1          8          1          8          3
         8          1          8          3          9          3
         5          1          8          3          9          3
         6          2          9          1          8          4
         8          2          9          1          8          4
         9          2          9          1          8          4
         5          2          9          2         14          4
         6          3         10          2         14          1
         2          3         11          1          8          1

17行が選択されました。

その他、COUNTの例としてGROUP BY句のテーブルカラム値に加工を用いる場合と、FROM句内の副問合せでの利用を示します。

SQL> SELECT SUBSTR(備考,1,3) AS 分類 , COUNT(売上数量) FROM TT_売上明細
  2  GROUP BY SUBSTR(備考,1,3)
  3  ORDER BY SUBSTR(備考,1,3);

分類   COUNT(売上数量)
------ ---------------
***                  1
CRT                  5
HUB                  1
NOT                  3
PC-                  2
PRT                  5

6行が選択されました。


SQL> SELECT TT.商品コード,TT.商品件数,TC.全件数,(TT.商品件数 / TC.全件数) * 100 AS 構成比
  2  FROM (
  3   SELECT 商品コード,COUNT(商品コード) AS 商品件数 FROM TT_売上明細
  4   GROUP BY 商品コード
  5  ) TT,
  6  (
  7   SELECT COUNT(商品コード) AS 全件数 FROM TT_売上明細
  8  ) TC;

商品コード   商品件数     全件数     構成比
---------- ---------- ---------- ----------
         1          1         17 5.88235294
         2          1         17 5.88235294
         3          1         17 5.88235294
         4          1         17 5.88235294
         5          1         17 5.88235294
         6          1         17 5.88235294
         7          2         17 11.7647059
         8          3         17 17.6470588
         9          4         17 23.5294118
        10          1         17 5.88235294
        11          1         17 5.88235294

11行が選択されました。

COUNT の対象が全くデータが無い状態では「0」が返される


集計(グループ)の対象のデータが全く無く NULL である場合は値が「0」で返されます。 以下のSQLは得意先コード毎に売上明細の件数を表示する例ですが、テーブルを 等結合 としているため、 売上が存在しない得意先コード「6」のデータが表示されません。
SQL> SELECT TM.得意先コード, COUNT(TD.売上番号) AS 売上明細件数
  2  FROM TM_得意先 TM, TT_売上 TH, TT_売上明細 TD
  3  WHERE TM.得意先コード = TH.得意先コード
  4  AND   TH.売上番号 = TD.売上番号
  5  GROUP BY TM.得意先コード
  6  ORDER BY TM.得意先コード;

得意先コード 売上明細件数
------------ ------------
           1           12
           2            3
           3            2
           4            1
           5            2

ここで 外部結合 (+) (LEFT JOIN) に変更すると、得意先コード「6」のデータが「0」で表示されます。
SQL> SELECT TM.得意先コード, COUNT(TD.売上番号) AS 売上明細件数
  2  FROM TM_得意先 TM, TT_売上 TH, TT_売上明細 TD
  3  WHERE TM.得意先コード = TH.得意先コード(+)
  4  AND   TH.売上番号 = TD.売上番号(+)
  5  GROUP BY TM.得意先コード
  6  ORDER BY TM.得意先コード;

得意先コード 売上明細件数
------------ ------------
           1           12
           2            3
           3            2
           4            1
           5            2
           6            0

6行が選択されました。