タイガー!タイガー!じれったいぞー!(SE編)

AS400, Java, JavaEE, JSF等の開発、習慣など。日々の気づきをまとめたブログ(備忘録)

【SQL】UNION ALLした統合結果をさらにグループ化する

業務の中で、下記のような集計処理を行う機会があり、 少しハマってしまったので、公開しておきます。

ちなみにRDBは、DB2 for IBM i (V7R3M0) になります。

やりたいことは、テーブルAを集計した結果とテーブルBを集計した結果を統合したものを
さらにグループ化して金額を集計することでした。

簡単なイメージとしては、次の図のようなイメージ。

f:id:no14141:20211201174131j:plain

集計し、結合したものを再集計する感じです。

SQL文は次のようになりました。

SELECT
    KEY1,
    KEY2,
    SUM(AMOUNT) AS AMOUNT
FROM
    (
        SELECT
            AKEY1 AS KEY1,
            AKEY2 AS KEY2,
            SUM(AAMOUNT) AS AMOUNT
        FROM
            LIB1.TBLA
        WHERE
            AFIELD1 = '10'
        GROUP BY
            AKEY1,
            AKEY2
        UNION ALL
        SELECT
            BKEY1 AS KEY1,
            BKEY2 AS KEY2,
            SUM(BAMOUNT) AS AMOUNT
        FROM
            LIB1.TBLB
        WHERE
            BFIELD1 = '10'
        GROUP BY
            BKEY1,
            BKEY2
    )
GROUP BY
    KEY1,
    KEY2

しかし、実行結果はエラーとなり、次のようなメッセージが吐き出されました。

SQL0199: キーワードBYは必要でない。
有効なトークンはFOR USE SKIP WAIT WITH FETCH LIMIT ORDER UNION EXCEPT OFFSETです。

メンバーに聞いてみたところ、以前同じ場面に遭遇したようで、 DB2系では統合した表に名前を付ける必要があるとのこと。

なるほど。

時々、AS句を省略してしまうクセがいけなかったわけですね。

仕切り直しです。

正しく動作するSQL

SELECT
    KEY1,
    KEY2,
    SUM(AMOUNT) AS AMOUNT
FROM
    (
        SELECT
            AKEY1 AS KEY1,
            AKEY2 AS KEY2,
            SUM(AAMOUNT) AS AMOUNT
        FROM
            LIB1.TBLA
        WHERE
            AFIELD1 = '10'
        GROUP BY
            AKEY1,
            AKEY2
        UNION ALL
        SELECT
            BKEY1 AS KEY1,
            BKEY2 AS KEY2,
            SUM(BAMOUNT) AS AMOUNT
        FROM
            LIB1.TBLB
        WHERE
            BFIELD1 = '10'
        GROUP BY
            BKEY1,
            BKEY2
    ) AS TBLS  -- 名前付けしないとエラーになる!
GROUP BY
    KEY1,
    KEY2

正常に集計することができました!