【問題1】文字位置指定検索

SELECT
    MEMBER_CODE AS CODE
    , LAST_NAME AS L_NAME
    , FIRST_NAME AS F_NAME 
FROM
    MEMBER_MST 
WHERE

    -- 先頭に任意の1文字を指定する'_'を、
    -- 検索文字の後に0文字以上の任意の文字列を指定する'%'を記述する
    LAST_NAME LIKE '_田%' 
ORDER BY
    MEMBER_CODE DESC;

【問題2】名称比較

SELECT
    IT.ITEM_CODE AS CODE

    -- NULLIF関数で、比較する項目が同じ場合はNULLを返す
    , NULLIF(IT.ITEM_NAME, ITH.ITEM_NAME) AS NAME 
FROM
    ITEM AS IT 

    -- 商品テーブルの全てのデータを表示するため、商品履歴テーブルを外部結合する
    LEFT OUTER JOIN ITEM_HISTORY AS ITH 
        ON ITH.ITEM_CODE = IT.ITEM_CODE 
ORDER BY
    IT.ITEM_CODE DESC;

【問題3】空席検索

SELECT
    SV1.LINE_ID AS LINE
    , SV1.SEAT_NO AS SEAT_F

    -- グルーピングした最大(3件目)の座席番号を取得
    , MAX(SV2.SEAT_NO) AS SEAT_T 
FROM
    SEAT_RESERVE AS SV1 

    -- 3番目の座席番号を取得するために、同一テーブルを自己結合する
    INNER JOIN SEAT_RESERVE AS SV2 
        ON SV1.LINE_ID = SV2.LINE_ID 
WHERE

   -- チェックする先頭の座席番号から3番目までの座席番号を順番に取得する
    SV2.SEAT_NO BETWEEN SV1.SEAT_NO AND SV1.SEAT_NO + (3 - 1) 
GROUP BY

    -- 取得した3件のデータを列ID、座席番号でグルーピング
    SV1.LINE_ID
    , SV1.SEAT_NO 
HAVING

    -- NULLIF関数で予約状況='1'の場合はカウント対象外として
    -- 予約状況='0'が3件続いている場合を対象とする
    COUNT(NULLIF(SV2.RSV_STATUS, '1')) = 3 
ORDER BY
    SV1.LINE_ID DESC
    , SV1.SEAT_NO ASC;

【問題4】体重差分

WITH SUB1 AS ( 

    -- 中間テーブルで対象データの体重と実施日が1つ前の体重を横並びに保持する
    SELECT
        HC1.CHECKUP_DATE
        , HC1.MEMBER_CODE
        , HC1.WEIGHT

        -- LAG関数で会員毎に実施日が1つまえの体重を取得
        , LAG(HC1.WEIGHT, 1) OVER ( 
            PARTITION BY
                HC1.MEMBER_CODE 
            ORDER BY
                HC1.CHECKUP_DATE
        ) AS BEFORE_WT 
    FROM
        HEALTH_CHECKUP AS HC1
) 
SELECT
    SUB1.CHECKUP_DATE AS CK_DATE
    , SUB1.MEMBER_CODE AS CODE
    , LAST_NAME || FIRST_NAME AS NAME

    -- 丸め誤差が発生するため、10倍して計算した結果を10で割る
    , (SUB1.WEIGHT * 10 - SUB1.BEFORE_WT * 10) / 10 AS CHG_WT 
FROM
    SUB1 

    -- 会員の姓名を取得するために、会員コードで会員テーブルを内部結合する
    INNER JOIN MEMBER_MST AS MM 
        ON MM.MEMBER_CODE = SUB1.MEMBER_CODE 
WHERE
    SUB1.CHECKUP_DATE = ( 

        -- 会員毎に直近の実施日を取得して比較する
        SELECT
            MAX(CHECKUP_DATE) 
        FROM
            HEALTH_CHECKUP 
        WHERE
            MEMBER_CODE = SUB1.MEMBER_CODE
    ) 

    -- 計算結果の絶対値が5以上のデータを対象とする
    AND ABS((SUB1.WEIGHT * 10 - SUB1.BEFORE_WT * 10) / 10) >= 5 
ORDER BY
    CHG_WT DESC
    , CODE DESC;