助け合いフォーラム
Oracle Master Silver SQL 2019(1Z0-071)
問題ID : 26871
問題を開く
PAYMENTS表の構造を確認して下さい。

15時より前に完了した決済の日時(PAYMENT_DATE)と金額(PAYMENT_AMT)のレポートを作成します。
金額が入っていない場合は「-1」と表示します。
どの問合せを実行しますか(該当するものを全て選択して下さい)。
ただし、実行環境は日本語環境とし、PAYMENT_AMT列を次の形式で表示します。
例) ¥10,000

15時より前に完了した決済の日時(PAYMENT_DATE)と金額(PAYMENT_AMT)のレポートを作成します。
金額が入っていない場合は「-1」と表示します。
どの問合せを実行しますか(該当するものを全て選択して下さい)。
ただし、実行環境は日本語環境とし、PAYMENT_AMT列を次の形式で表示します。
例) ¥10,000
正解
SELECT TO_CHAR(payment_date, 'RR-MM-DD HH24:MI:SS') "決済日時", NVL(TO_CHAR(payment_amt, 'L99,999,999'), -1) "金額"
FROM payments
WHERE TO_CHAR(payment_date, 'HH24') < 15;
SELECT TO_CHAR(payment_date, 'RR-MM-DD HH24:MI:SS') "決済日時", COALESCE(TO_CHAR(payment_amt, 'L99,999,999'), '-1') "金額"
FROM payments
WHERE TO_CHAR(payment_date, 'HH24') < 15;
解説
TIMESTAMP型はDATE型を拡張したデータ型で、世紀、年、月、日、時、分、秒に加え、秒の小数点以下の値を格納できます。
設問の条件のように15時より前のPAYMENT_DATEを取り出すには、TO_CHAR(payment_date, 'HH24') < 15で、15時より前の時間を検索します。ここでは文字列→数値への暗黙的なデータ変換が行われます。
PAYMENT_AMT列を設問の書式にするには、TO_CHAR(payment_amt, 'L99,999,999')を指定します。
では、選択肢を1つずつ確認してみましょう。
・SELECT TO_CHAR(payment_date, 'RR-MM-DD HH24:MI:SS') "決済日時", NVL(TO_CHAR(payment_amt, 'L99,999,999'), '未入力') "金額"
FROM payments
WHERE TO_DATE(payment_date, 'HH24') < 15;
WHERE句の条件にTO_DATE(payment_date, 'HH24') < 15が指定されていますが、数値<->日付値の変換は行われませんので、データ型の不一致でエラーとなります。誤ったSQL文です。
・SELECT TO_CHAR(payment_date, 'RR-MM-DD HH24:MI:SS') "決済日時", NVL(TO_CHAR(payment_amt, 'L99,999,999'), -1) "金額"
FROM payments
WHERE TO_CHAR(payment_date, 'HH24') < 15;
NVL(TO_CHAR(payment_amt, 'L99,999,999'), -1)で、PAYMENT_AMT列がNULL値であれば-1を、そうでなければ書式化した文字列になるように指定しています。NVLの第1引数が文字列で第2引数が数値ですが、暗黙的なデータ変換が行われるためエラーとなりません。正しいSQL文です。

・SELECT TO_CHAR(payment_date, 'RR-MM-DD HH24:MI:SS') "決済日時", NVL2(payment_amt, TO_NUMBER(payment_amt, 'L99,999,999'), -1) "金額"
FROM payments
WHERE TO_CHAR(payment_date, 'HH24') < 15;
TO_NUMBER(payment_amt, 'L99,999,999')に指定した引数が無効なためエラーとなります。誤ったSQL文です。
・SELECT TO_CHAR(payment_date, 'RR-MM-DD HH24:MI:SS') "決済日時", COALESCE(TO_CHAR(payment_amt, 'L99,999,999'), '-1') "金額"
FROM payments
WHERE TO_CHAR(payment_date, 'HH24') < 15;
COALESCE(TO_CHAR(payment_amt, 'L99,999,999'), '-1')で、PAYMENT_AMT列がNULL値であれば'-1'を、そうでなければ書式化した文字列になるように指定しています。COALESCE関数の引数は全て同じデータ型でなければならず暗黙的なデータ変換は行われないため、'-1'というように文字列を指定しています。正しいSQL文です。

設問の条件のように15時より前のPAYMENT_DATEを取り出すには、TO_CHAR(payment_date, 'HH24') < 15で、15時より前の時間を検索します。ここでは文字列→数値への暗黙的なデータ変換が行われます。
PAYMENT_AMT列を設問の書式にするには、TO_CHAR(payment_amt, 'L99,999,999')を指定します。
では、選択肢を1つずつ確認してみましょう。
・SELECT TO_CHAR(payment_date, 'RR-MM-DD HH24:MI:SS') "決済日時", NVL(TO_CHAR(payment_amt, 'L99,999,999'), '未入力') "金額"
FROM payments
WHERE TO_DATE(payment_date, 'HH24') < 15;
WHERE句の条件にTO_DATE(payment_date, 'HH24') < 15が指定されていますが、数値<->日付値の変換は行われませんので、データ型の不一致でエラーとなります。誤ったSQL文です。
・SELECT TO_CHAR(payment_date, 'RR-MM-DD HH24:MI:SS') "決済日時", NVL(TO_CHAR(payment_amt, 'L99,999,999'), -1) "金額"
FROM payments
WHERE TO_CHAR(payment_date, 'HH24') < 15;
NVL(TO_CHAR(payment_amt, 'L99,999,999'), -1)で、PAYMENT_AMT列がNULL値であれば-1を、そうでなければ書式化した文字列になるように指定しています。NVLの第1引数が文字列で第2引数が数値ですが、暗黙的なデータ変換が行われるためエラーとなりません。正しいSQL文です。

SQLを表示
SELECT TO_CHAR(payment_date, 'RR-MM-DD HH24:MI:SS') "決済日時", NVL(TO_CHAR(payment_amt, 'L99,999,999'), -1) "金額"
FROM payments
WHERE TO_CHAR(payment_date, 'HH24') < 15;
FROM payments
WHERE TO_CHAR(payment_date, 'HH24') < 15;
・SELECT TO_CHAR(payment_date, 'RR-MM-DD HH24:MI:SS') "決済日時", NVL2(payment_amt, TO_NUMBER(payment_amt, 'L99,999,999'), -1) "金額"
FROM payments
WHERE TO_CHAR(payment_date, 'HH24') < 15;
TO_NUMBER(payment_amt, 'L99,999,999')に指定した引数が無効なためエラーとなります。誤ったSQL文です。
・SELECT TO_CHAR(payment_date, 'RR-MM-DD HH24:MI:SS') "決済日時", COALESCE(TO_CHAR(payment_amt, 'L99,999,999'), '-1') "金額"
FROM payments
WHERE TO_CHAR(payment_date, 'HH24') < 15;
COALESCE(TO_CHAR(payment_amt, 'L99,999,999'), '-1')で、PAYMENT_AMT列がNULL値であれば'-1'を、そうでなければ書式化した文字列になるように指定しています。COALESCE関数の引数は全て同じデータ型でなければならず暗黙的なデータ変換は行われないため、'-1'というように文字列を指定しています。正しいSQL文です。

SQLを表示
SELECT TO_CHAR(payment_date, 'RR-MM-DD HH24:MI:SS') "決済日時", COALESCE(TO_CHAR(payment_amt, 'L99,999,999'), '-1') "金額"
FROM payments
WHERE TO_CHAR(payment_date, 'HH24') < 15;
FROM payments
WHERE TO_CHAR(payment_date, 'HH24') < 15;
参考
NULL値を扱う汎用関数には次の関数があります。
[NVL関数]
NVL関数は値がNULL値であった場合に、別の値を返す関数です。
使用法は以下の通りです。
NVL(式1, 式2)
第1引数の値がNULL値の場合、第2引数の値を返します。第1引数の値がNULL値でなければ、そのまま第1引数の値を返します。

ただし、第2引数に指定する式は、第1引数のデータ型と同じデータ型でなければなりません(暗黙的なデータ変換が行われる場合はエラーとなりません)。異なるデータ型を返す式を指定するとエラーとなります。

[NVL2関数]
NVL2関数は値がNULL値か否かを調べ、NULL値以外の場合は値A、NULL値の場合は値Bを返す関数です。
使用法は以下の通りです。
NVL2(式1, 式2, 式3)
第1引数の値がNULL値以外の場合、第2引数の値を返します。
第1引数の値がNULL値の場合、第3引数の値を返します。

ただし、第2引数と第3引数は同じデータ型でなければなりません(暗黙的なデータ変換が行われる場合はエラーとなりません)。異なるデータ型を返す式を指定するとエラーとなります。

[NULLIF関数]
NULLIF関数は2つの値を比較して、等しい場合にNULLを返す関数です。
使用法は以下の通りです。
NULLIF(式1, 式2)
第1引数と第2引数が等しい場合はNULL値を、等しくない場合は第1引数の値を返します。

なお、第1引数にはリテラルのNULL値以外の値を指定しなければなりません。

上記のように第1引数にリテラルのNULL値は指定できませんが、第1引数で指定した列の値などが結果としてNULL値となる場合は問題ありません。
第1引数が結果としてNULL値となる場合は、第2引数がいかなる値であっても、NULL値が返されます。(第2引数がNULL値であれば等しいのでNULL値、第2引数がNULL値以外であれば等しくないので第1引数のNULL値が返される為)
[COALESCE関数]
COALESCE関数は引数の値を判定し、最初に見つかったNULL値以外の値を返す関数です。
使用法は以下の通りです。
COALESCE(式1, 式2 [, 式3 ...])
引数に指定された式全てがNULL値の場合、COALESCE関数はNULL値を返します。

なお、COALESCE関数の引数は、すべて同じデータ型の値でなければなりません。異なるデータ型の値を指定するとエラーとなります(暗黙的なデータ変換は行われません)。

[NVL関数]
NVL関数は値がNULL値であった場合に、別の値を返す関数です。
使用法は以下の通りです。
NVL(式1, 式2)
第1引数の値がNULL値の場合、第2引数の値を返します。第1引数の値がNULL値でなければ、そのまま第1引数の値を返します。

SQLを表示
SELECT employee_id, employee_name, salary
FROM employees
WHERE employee_id IN (1017, 1018, 1019);
SELECT employee_id, employee_name, NVL(salary, 0)
FROM employees
WHERE employee_id IN (1017, 1018, 1019);
FROM employees
WHERE employee_id IN (1017, 1018, 1019);
SELECT employee_id, employee_name, NVL(salary, 0)
FROM employees
WHERE employee_id IN (1017, 1018, 1019);
ただし、第2引数に指定する式は、第1引数のデータ型と同じデータ型でなければなりません(暗黙的なデータ変換が行われる場合はエラーとなりません)。異なるデータ型を返す式を指定するとエラーとなります。

SQLを表示
SELECT NVL(manager_id, 'none')
FROM employees;
FROM employees;
[NVL2関数]
NVL2関数は値がNULL値か否かを調べ、NULL値以外の場合は値A、NULL値の場合は値Bを返す関数です。
使用法は以下の通りです。
NVL2(式1, 式2, 式3)
第1引数の値がNULL値以外の場合、第2引数の値を返します。
第1引数の値がNULL値の場合、第3引数の値を返します。

SQLを表示
SELECT salary, NVL2(salary, 1, 0)
FROM employees;
FROM employees;
ただし、第2引数と第3引数は同じデータ型でなければなりません(暗黙的なデータ変換が行われる場合はエラーとなりません)。異なるデータ型を返す式を指定するとエラーとなります。

SQLを表示
SELECT NVL2(commission, commission, 'none')
FROM employees;
FROM employees;
[NULLIF関数]
NULLIF関数は2つの値を比較して、等しい場合にNULLを返す関数です。
使用法は以下の通りです。
NULLIF(式1, 式2)
第1引数と第2引数が等しい場合はNULL値を、等しくない場合は第1引数の値を返します。

SQLを表示
SELECT employee_name, salary, commission, NULLIF(salary, commission/4)
FROM employees;
FROM employees;
なお、第1引数にはリテラルのNULL値以外の値を指定しなければなりません。

SQLを表示
SELECT NULLIF(NULL, 'database')
FROM dual;
FROM dual;
上記のように第1引数にリテラルのNULL値は指定できませんが、第1引数で指定した列の値などが結果としてNULL値となる場合は問題ありません。
第1引数が結果としてNULL値となる場合は、第2引数がいかなる値であっても、NULL値が返されます。(第2引数がNULL値であれば等しいのでNULL値、第2引数がNULL値以外であれば等しくないので第1引数のNULL値が返される為)
[COALESCE関数]
COALESCE関数は引数の値を判定し、最初に見つかったNULL値以外の値を返す関数です。
使用法は以下の通りです。
COALESCE(式1, 式2 [, 式3 ...])
引数に指定された式全てがNULL値の場合、COALESCE関数はNULL値を返します。

SQLを表示
SELECT commission, salary, employee_id,
COALESCE(commission, salary, employee_id)
FROM employees
WHERE employee_id >= 1016;
COALESCE(commission, salary, employee_id)
FROM employees
WHERE employee_id >= 1016;
なお、COALESCE関数の引数は、すべて同じデータ型の値でなければなりません。異なるデータ型の値を指定するとエラーとなります(暗黙的なデータ変換は行われません)。

SQLを表示
SELECT COALESCE(employee_id, employee_name, hiredate)
FROM employees;
FROM employees;
なぜ引数が無効になるのでしょうか
t
taichi_y
投稿日 2025/03/18
TO_NUMBER(payment_amt, 'L99,999,999')に指定した引数が無効なためエラーとなります。誤ったSQL文です。
上記の場合なぜ引数が無効になるのでしょうか?
この投稿に対して返信しませんか?
t taichi_y
2025/03/19 22:00
ありがとうございます。理解できました。