ソースコード
WITH TOTAL_SALES AS ( 
    -- 対象期間の売上データの売上金額の総合計を取得する
    SELECT
        SUM(SALES_AMT) AS TOTAL_AMT 
    FROM
        SALES 
    WHERE
        SALES_DATE BETWEEN '2023-06-01' AND '2023-06-30'
) 
, SUM_ITEM AS ( 
    -- 商品毎に対象期間の売上金額合計を取得する
    SELECT
        SAD.ITEM_CODE
        , SUM(SAD.UNITPRICE * SAD.SALES_QTY) AS AMT 
    FROM
        SALES AS SA 
        -- 販売単価、売上数量を取得するために売上データ明細を内部結合
        INNER JOIN SALES_DTL AS SAD 
            ON SA.SALES_NO = SAD.SALES_NO 
    WHERE
        SA.SALES_DATE BETWEEN '2023-06-01' AND '2023-06-30' 
    GROUP BY
        SAD.ITEM_CODE
) 
, CUMUL_SALES AS ( 
    -- 上記の商品毎の売上金額合計をもとに、売上金額の降順に累積金額を取得
    SELECT
        ITEM_CODE
        , AMT
        -- SUM関数とOVER句で累積金額を取得
        -- 売上合計が同じ場合は、同じ商品の売上金額を合計した値が累積金額になる
        -- B,Cの売上金額が100で同じなので、B,Cの売上金額を加算した200を前のレコードの350に加算して、
        -- B,Cそれぞれの累積金額は同額の550になる
        --+--------+---------+---------+
        --| コード | 売上合計 | 累積金額 |
        --+--------+---------+---------+
        --|    A   |     350 |     350 |
        --+--------+---------+---------+
        --|    B   |     100 |     550 |
        --+--------+---------+---------+
        --|    C   |     100 |     550 |
        --+--------+---------+---------+
        , SUM(AMT) OVER (ORDER BY (AMT) DESC) AS CUMUL_AMT 
    FROM
        SUM_ITEM
) 
SELECT
    CS.ITEM_CODE AS CODE
    , ITEM_NAME AS NAME
    , CS.AMT AS SAL_AMT
    , CS.CUMUL_AMT AS CML_AMT
    -- 小数点を計算するので、CAST関数でREAL型に変換して、結果をROUND関数で四捨五入する
    , ROUND((CAST(CS.AMT AS REAL) / TS.TOTAL_AMT * 100), 1) || '%' AS SAL_COMP
    , ROUND( 
        (CAST(CS.CUMUL_AMT AS REAL) / TS.TOTAL_AMT * 100)
        , 1
    ) || '%' AS TTL_COMP
    -- CASE句で計算結果によりランク分けをおこなう
    , CASE 
        WHEN ROUND( 
            (CAST(CS.CUMUL_AMT AS REAL) / TS.TOTAL_AMT * 100)
            , 1
        ) <= 40 
            THEN 'A' 
        WHEN ROUND( 
            (CAST(CS.CUMUL_AMT AS REAL) / TS.TOTAL_AMT * 100)
            , 1
        ) <= 80 
            THEN 'B' 
        ELSE 'C' 
        END AS RANK 
FROM
    CUMUL_SALES AS CS 
    -- 各レコードで使用するため、1レコードのみの総合計金額をCROSS結合
    CROSS JOIN TOTAL_SALES AS TS 
    -- 商品名を取得するため、商品テーブルを内部結合
    INNER JOIN ITEM 
        ON ITEM.ITEM_CODE = CS.ITEM_CODE 
ORDER BY
    CS.AMT DESC
    ,CS.ITEM_CODE DESC;
提出情報
提出日時2023/06/14 10:44:21
コンテスト第7回 SQLコンテスト
問題ABC分析
受験者admin
状態 (詳細)AC
(Accepted: 正答)
メモリ使用量79 MB
メッセージ
テストケース(通過数/総数)
3/3
状態
メモリ使用量
データパターン1
AC
79 MB
データパターン2
AC
78 MB
データパターン3
AC
78 MB