助け合いフォーラム

Oracle DB

Oracle Master Silver SQL 2019(1Z0-071)
問題ID : 26850
問題を開く
CUSTOMERS表の構造を確認して下さい。



顧客名と、郵便番号の「-(ハイフン)」より後ろの数字を「*」に置き換えて表示します。
どのSQL文を使用しますか。

顧客名  郵便番号
------ ----------
田中浩二  142-****
佐々木二郎 146-****
山口真弓  142-****

正解

SELECT cust_last_name || cust_first_name "顧客名",
 RPAD(SUBSTR(cust_postal_code, 1, INSTR(cust_postal_code, '-')), LENGTH(cust_postal_code), '*') "郵便番号"
FROM customers;

解説

選択肢のSQL文を1つずつ確認してみましょう。

・SELECT cust_last_name || cust_first_name "顧客名",
 RPAD(SUBSTR(cust_postal_code, 1, INSTR(cust_postal_code, '-')),  LENGTH(cust_postal_code), '*') "郵便番号"
 FROM customers;
INSTR(cust_postal_code, '-')でCUST_POSTAL_CODEの「-(ハイフン)」の位置を抽出し、
SUBSTR(cust_postal_code, 1, INSTR(cust_postal_code, '-')でCUST_POSTAL_CODEの先頭から「-(ハイフン)」までの文字列を抽出します。
抽出した文字列に、RPAD関数でLENGTH(cust_postal_code) = CUST_POSTAL_CODEの文字数分になるように右側に「*」を埋め込みます。
このSQL文が正解です。


SQLを表示
SELECT cust_last_name || cust_first_name "顧客名",
 RPAD(SUBSTR(cust_postal_code, 1, INSTR(cust_postal_code, '-')),  LENGTH(cust_postal_code), '*') "郵便番号"
 FROM customers;


・SELECT cust_last_name || cust_first_name "顧客名",
 LPAD(SUBSTR(cust_postal_code, INSTR(cust_postal_code,'-')), LENGTH(cust_postal_code), '*') "郵便番号"
 FROM customers;
SUBSTR(cust_postal_code, INSTR(cust_postal_code,'-')では、「-(ハイフン)」から末尾までを抽出します。
LPAD関数は文字列の左側に「*」を埋め込むので以下のような結果となります。誤ったSQL文です。


SQLを表示
SELECT cust_last_name || cust_first_name "顧客名",
 LPAD(SUBSTR(cust_postal_code, INSTR(cust_postal_code,'-')), LENGTH(cust_postal_code), '*') "郵便番号"
 FROM customers;


・SELECT cust_last_name || cust_first_name "顧客名",
 RPAD(SUBSTR(cust_postal_code, INSTR(cust_postal_code,'-')), LENGTH(cust_postal_code) - INSTR(cust_postal_code,'-'), '*') "郵便番号"
 FROM customers;
SUBSTR(cust_postal_code, INSTR(cust_postal_code,'-')では、「-(ハイフン)」から末尾までを抽出します。
また、RPADの引数にCUST_POSTAL_CODEの文字数 - 「-(ハイフン)」の位置が指定されているので、以下のような結果となります。誤ったSQL文です。


SQLを表示
SELECT cust_last_name || cust_first_name "顧客名",
 RPAD(SUBSTR(cust_postal_code, INSTR(cust_postal_code,'-')), LENGTH(cust_postal_code) - INSTR(cust_postal_code,'-'), '*') "郵便番号"
 FROM customers;


・ SELECT cust_last_name || cust_first_name "顧客名",
 RPAD(SUBSTR(cust_postal_code, 1, INSTR(cust_postal_code, '-')), LENGTH(cust_postal_code), '*' "郵便番号"
 FROM customers;
'*'の後に右括弧)が足りず、エラーとなります。誤ったSQL文です。

参考

LPAD関数は、単一行関数のうちの文字関数に分類されます。
引数で指定された文字列が長さnの文字列になるように、左側に指定された埋め込み文字を付加した文字列を返します。
使用法は以下の通りです。

 LPAD(文字列, n, '埋め込み文字')

LPAD関数と同様に文字列の右側に埋め込み文字を付加する関数がRPAD関数です。

 RPAD(文字列, n, '埋め込み文字')

その他、主な文字関数には次のものがあります。

上に戻る

馬鹿な私を助けてください。

公開日 2024/01/24

誤解答の一つの下記の内容について質問です。

・SELECT cust_last_name || cust_first_name "顧客名",
 RPAD(SUBSTR(cust_postal_code, INSTR(cust_postal_code,'-')), LENGTH(cust_postal_code) - INSTR(cust_postal_code,'-'), '') "郵便番号"
 FROM ![customers;]
SUBSTR(cust_postal_code, INSTR(cust_postal_code,'-')では、「-(ハイフン)」から末尾までを抽出します。
また、RPADの引数にCUST_POSTAL_CODEの文字数 -「-(ハイフン)」の位置が指定されているので、以下のような結果となります。誤ったSQL文です。
という解説があり郵便番号が各行[-006 ]のような結果になるみたいですが、
私のイメージだとRPADの引数に CUST_POSTAL_CODEの文字数(8)ー「-(ハイフン)」の位置(4)=4となり郵便番号の後に'
'が4つ付くことで各行[-006****]のような結果が出ると思いました。何故、この結果にはならないのでしょうか。教えてくださる方がいれば、ご教授お願い致します。

2024/01/24 21:10

RPADやLPADの第2引数は「表示される全体の長さ」で、第1引数の文字列の長さが第2引数で指定された長さよりも長い場合には、第2引数で指定された長さまでのみ表示され、残りは切り捨てられます。

SUBSTR(cust_postal_code, INSTR(cust_postal_code, '-'))
→ 「-0063」※長さ 5

LENGTH(cust_postal_code) - INSTR(cust_postal_code, '-')
→ 8 - 4 = 4

第一引数の文字列の長さ「5」、第2引数で指定された長さ「4」で、第一引数の方が長いため、RPADの結果は長さ4まで(「-0063」のうち「-006」まで)が表示されることになります。

参考URLのマニュアルだと、以下の部分ですね。

expr1がnより長い場合、このファンクションはnに収まるexpr1の一部を戻します。

あと、この問題の解説には書いてなかったのですが、他の問題(ID:26812)の解説に以下の記述がありました。

RPAD関数やLPAD関数の引数に指定された文字列が、長さで指定されたサイズよりも長い場合、次のように指定されたサイズ分の文字列が表示されます。


コメント

y yoshida11

2024/01/24 22:48

丁寧な説明ありがとうございます。 だからSQL文に記載の「*」が使われることなく、解説のような結果が表示されるということですね。 とても勉強になりました。 ID:26812の解説も見てきます。 本当にありがとうございました。

この返信に対して
コメントを記入できます

この投稿に対して返信しませんか?