0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

COBOLからOracle SQLへ移行 オープン系ではSUMなどのグループ関数を使って楽したいから配列は使わない。

0
Last updated at Posted at 2026-03-17

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
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?