COBOL 01 レベルで
000010 01 MONTHLY_SALES-REC. -- 月別売上
000020 02 BRANCH-CODE PIC 9(003). -- 支店コード
000030 02 GOODS-CODE PIC 9(006). -- 商品コード
000040 02 YEAR PIC 9(004) -- 年
000050 02 MONTHS-ARRAY OCCURS 12. . -- 月別
000060 03 MONTHS-SQTY PIC S9(007) COMP-3. -- 月別数量
000070 03 MONTHS-AMT PIC S9(011) COMP-3. -- 月別金額
があったとして、
-- ログを取得するパスはあらかじめ用意しておく
cd \tmp
-- SQL*Plus (Oracle Database に接続するソフト)を起動
-- ユーザーコード/おパスワード@DB接続子 はDBAに確認
sqlplus USER1/PASS1@DB1
-- DATE関係の書式マスクを変更
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY/MM/DD HH24:MI:SS' ;
``
Oracle SQLでは次のようなテーブル(配列ではない)になる。
```Oracle SQL
CREATE TABLE MONTHLY_SALES -- 月間売上
(
BRANCH_CODE NUMBER(3) NOT NULL -- 支店コード
, GOODS_CODE NUMBER(3) NOT NULL -- 商品コード
, SALES_YMD DATE NOT NULL -- 売上年月日
, MONTHS_QTY NUMBER(7) NOT NULL -- 月別数量
, MONTHS_AMT NUMBER(11) NOT NULL -- 月別金額
, CONSTRAINT PK_MONTHLY_SALES PRIMARY KEY(BRANCH_CODE, GOODS_CODE, SALES_YMD) USING INDEX
) ;
動作を説明するため数行データを用意する。
-- データとして、
INSERT INTO MONTHLY_SALES(BRANCH_CODE, GOODS_CODE, SALES_YMD, MONTHS_QTY, MONTHS_AMT)
VALUES( 10, 100, TO_DATE('2026/01/01', 'YYYY/MM/DD'), 100, 10000) ;
INSERT INTO MONTHLY_SALES(BRANCH_CODE, GOODS_CODE, SALES_YMD, MONTHS_QTY, MONTHS_AMT)
VALUES( 20, 200, TO_DATE('2026/02/01', 'YYYY/MM/DD'), 200, 20000) ;
INSERT INTO MONTHLY_SALES(BRANCH_CODE, GOODS_CODE, SALES_YMD, MONTHS_QTY, MONTHS_AMT)
VALUES( 30, 300, TO_DATE('2026/03/01', 'YYYY/MM/DD'), 300, 30000) ;
-- 中略
INSERT INTO MONTHLY_SALES(BRANCH_CODE, GOODS_CODE, SALES_YMD, MONTHS_QTY, MONTHS_AMT)
VALUES(120, 120, TO_DATE('2026/12.01', 'YYYY/MM/DD'), 1200, 120000) ;
COMMIT ;
-- 支店コード, 商品コード, 売上年, さらに横に1月から12月の月別数量、月別金額 を1行に並べるSELECT文
以下のSQLなどを拡張子 sql の英数字と_(アンダーバー)からなるテキスト・ファイルに作成してsqlplusにスクリプトから実行
SET ECHO OFF
SET FEEDBACK OFF
SET LINESIZE 300
SET PAGESIZE 100
SET TERMOUT OFF
SET TRIMSPOOL ON
SPOOL monthly_sales.csv
SELECT
MS.BRANCH_CODE
, MS.GOODS_CODE
, EXTRACT(YEAR FROM MS.SALES_YMD) AS SALES_Y
-- 1月
, SUM(DECODE(EXTRACT(MONTH FROM MS.SALES_YMD), 1, MS.MONTHS_QTY, 0)) AS M01_QTY
, SUM(DECODE(EXTRACT(MONTH FROM MS.SALES_YMD), 1, MS.MONTHS_AMT, 0)) AS M01_AMT
-- 2月
, SUM(DECODE(EXTRACT(MONTH FROM MS.SALES_YMD), 2, MS.MONTHS_QTY, 0)) AS M02_QTY
, SUM(DECODE(EXTRACT(MONTH FROM MS.SALES_YMD), 2, MS.MONTHS_AMT, 0)) AS M02_AMT
-- 3月
, SUM(DECODE(EXTRACT(MONTH FROM MS.SALES_YMD), 3, MS.MONTHS_QTY, 0)) AS M03_QTY
, SUM(DECODE(EXTRACT(MONTH FROM MS.SALES_YMD), 3, MS.MONTHS_AMT, 0)) AS M03_AMT
-- 中略
-- 12月
, SUM(DECODE(EXTRACT(MONTH FROM MS.SALES_YMD), 12, MS.MONTHS_QTY, 0)) AS M12_QTY
, SUM(DECODE(EXTRACT(MONTH FROM MS.SALES_YMD), 12, MS.MONTHS_AMT, 0)) AS M12_AMT
FROM MONTHLY_SALES MS
GROUP BY
MS.BRANCH_CODE
, MS.GOODS_CODE
, EXTRACT(YEAR FROM MS.SALES_YMD)
ORDER BY
MS.BRANCH_CODE
, SALES_Y ;
spool off
SET ECHO ON
SET FEEDBACK ON
-- SPOOLは実行結果をログに落とす。結果はテキスト・ファイルだから、エディタで確認したり、今回の拡張子はcsvだからエクスプローラーでExcelで開いて確認する。
BRANCH_CODE GOODS_CODE SALES_Y M01_QTY M01_AMT M02_QTY M02_AMT M03_QTY M03_AMT M04_QTY M04_AMT M05_QTY M05_AMT M06_QTY M06_AMT M07_QTY M07_AMT M08_QTY M08_AMT M09_QTY M09_AMT M10_QTY M10_AMT M11_QTY M11_AMT M12_QTY M12_AMT
----------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
10 100 2026 100 10000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
20 200 2026 0 0 200 20000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
30 300 2026 0 0 0 0 300 30000 0 0 0 0 0
-- 中略
120 120 2026 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1200 120000
12ヶ月分をひとつずつ書くのは大変なのでOracleのPIVOT句を使う
-- CSVとして列の区切りを , に
SET COLSEP ','
SET ECHO OFF
SET FEEDBACK OFF
SET LINESIZE 500
SET PAGESIZE 100
SET TERMOUT OFF
SET TRIMSPOOL ON
SPOOL monthly_sales_pivot.csv
SELECT *
FROM(
-- 1. 必要な列だけを抜き出し、月(M)と年(Y)を数値化する
SELECT
MS.BRANCH_CODE
, MS.GOODS_CODE
, EXTRACT(YEAR FROM MS.SALES_YMD) AS SALES_Y
, EXTRACT(MONTH FROM MS.SALES_YMD) AS SALES_M
, MS.MONTHS_QTY
, MS.MONTHS_AMT
FROM MONTHLY_SALES MS
)
PIVOT
(
-- 2. 横並びにしたい項目を集計(自動的に列が作られる)
SUM(MONTHS_QTY) AS QTY
, SUM(MONTHS_AMT) AS AMT
-- 3. 横に展開したい「月」を指定
FOR SALES_M IN(
1 AS "M01", 2 AS "M02", 3 AS "M03", 4 AS "M04", 5 AS "M05", 6 AS "M06"
, 7 AS "M07", 8 AS "M08", 9 AS "M09", 10 AS "M10", 11 AS "M11", 12 AS "M12"
)
)
ORDER BY
BRANCH_CODE
, GOODS_CODE
, SALES_Y ;
spool off
SET ECHO ON
SET FEEDBACK ON