コンテストの制限時間が終了しました。
以降も提出を行うことができますが、順位集計には反映されません。
以降も提出を行うことができますが、順位集計には反映されません。
【問題1】文字数チェック
SELECT
EMP_CODE AS CODE
, EMP_ENG_NAME AS NAME
, LENGTH(EMP_ENG_NAME) AS WORD_CNT
FROM
EMP
WHERE
LENGTH(EMP_ENG_NAME) >= 15
ORDER BY
WORD_CNT DESC
, EMP_CODE ASC;
【問題2】受注金額TOP5
SELECT
ODD.ITEM_CODE AS CODE
, IT.ITEM_NAME AS NAME
-- 販売単価と受注数量を掛けた値をSUM関数で集計します
, SUM(ODD.UNITPRICE * ODD.ORDER_QTY) AS TOTAL_AMT
FROM
-- メインテーブルを受注テーブルにしています
ORDERS AS OD
-- 商品コード、販売単価、受注数量を取得するために、受注明細テーブルを内部結合しています
INNER JOIN ORDERS_DTL AS ODD
ON OD.ORDER_NO = ODD.ORDER_NO
-- 商品名を取得するために、商品テーブルを内部結合しています
INNER JOIN ITEM AS IT
ON ODD.ITEM_CODE = IT.ITEM_CODE
WHERE
-- BETWEEN句を使用して受注日が範囲内のデータを抽出します
OD.ORDER_DATE BETWEEN '2023-05-14' AND '2023-05-20'
GROUP BY
-- 商品コード、商品名でグルーピングします
ODD.ITEM_CODE
, IT.ITEM_NAME
ORDER BY
TOTAL_AMT DESC
, ODD.ITEM_CODE DESC
-- LIMIT句で5件までの表示制御をしています
LIMIT
5;
【問題3】商品整理
DELETE
FROM
ITEM
WHERE
-- 在庫管理する商品が対象
STOCK_MANAGEMENT_TYPE = 1
AND (
-- 商品コードが在庫テーブルに存在しないこと確認
NOT EXISTS (
SELECT
ITEM_CODE
FROM
STOCK
WHERE
STOCK.ITEM_CODE = ITEM.ITEM_CODE
)
-- 商品コードが在庫テーブルに存在しているが、削除条件を満たしていることを確認
OR EXISTS (
SELECT
ITEM_CODE
FROM
STOCK
WHERE
STOCK.ITEM_CODE = ITEM.ITEM_CODE
-- 商品コードで集計した結果を判定するためグルーピングをおこなう
GROUP BY
ITEM_CODE
HAVING
-- 最終出荷日の最大値が6カ月以上前かチェック
-- 入荷実績があるがまだ出荷実績がない場合は、最終出荷日はNULLなので削除の対象外となる
-- (最終出荷日がNULLの場合は対象外とするため、ダミーで'2999-12-31'をセット)
MAX(IFNULL(LAST_DELIVERY_DATE, '2999-12-31')) <= DATE ('2023-06-01', '-6 months')
-- 実在庫数の合計がゼロかチェック
AND SUM(ACTUAL_AMT) = 0
)
);
【問題4】ABC分析
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;