4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

「LENGTH ~ -1」がわからない。SUBSTRINGの文を分解してみる_ 『スッキリわかるSQL入門』5章

Last updated at Posted at 2020-10-02

#はじめに
『スッキリわかるSQL入門第二版』5章の練習問題でつまずいたのでまとめます。
p165の問題5-2です。
解答を見ても、SUBSTRINGの文の意味を読み取ることができませんでした。

#問題の解答
あるアンケートの回答者のテーブルがあり、「メールアドレス、国名、性別、年齢」の列がある。それぞれにデータ型が定義されていて、国名は全てNULLとなっている。末尾2文字が国コードとなっているメールアドレスをもとにして、国名列を更新せよ、という問題でした。問題を転記するのが可なのかよくわからないので、問題の詳細はここでは書かないでおきます。

まず、解答はこれでした。

UPDATE 回答者
SET 国名 = CASE SUBSTRING(TRIM(メールアドレス),
                          LENGTH(TRIM(メールアドレス))-1, 2)
             WHEN 'jp' THEN '日本'
             WHEN 'uk' THEN 'イギリス'
             WHEN 'cn' THEN '中国'
             WHEN 'fr' THEN 'フランス'
             WHEN 'vn' THEN 'ベトナム' END

わからないのはこの部分。

CASE SUBSTRING(TRIM(メールアドレス),
               LENGTH(TRIM(メールアドレス))-1, 2)

ひとつひとつの関数の意味を復習してみます。

#CASE演算子
p144
構文①

CASE 評価する列や式 WHEN 値1 THEN 値1のときに返す値
          (WHEN 値2 THEN 値2のときに返す値)...
          (ELSE デフォルト値)
 END

構文②

CASE WHEN 条件1 THEN 条件1のときに返す値
          (WHEN 条件2 THEN 条件2のときに返す値)...
          (ELSE デフォルト値)
 END

#SUBSTRING関数
p154
「SUBSTRING関数」(読み:サブストリング)or「SUBSTR関数」
どちらを利用できるかは、DBMS製品によって違う。
「何文字目から何文字分」という指定をして文字列の一部分を抽出できる。

#TRIM関数
p152
「TRIM」(読み:トリム)=左右から空白を除去する
 (「LTRIM」(エルトリム)=左側から空白を除去する。「RTRIM」(アールトリム)=右側から空白を除去する。)

#LENGTH関数
p152
「LENGTH」(レングス)=文字列の長さを調べる。
(SQL Serverでは「LEN」(レン))p166)

#解答のコードにそれぞれの意味をあてはめてみる

CASE SUBSTRING(TRIM(メールアドレス),
               LENGTH(TRIM(メールアドレス))-1, 2)

・CASE
WHEN/THEN/ENDとセットなので、ここでは保留。

・SUBSTRING
文字列のうち次に指定する部分を抽出する。

・(TRIM(メールアドレス),
左右から空白を除去する。メールアドレスの列は 30桁のCHAR型(=固定長の文字列) だと定義されているので、その空白を除去するということ。

・LENGTH(TRIM(メールアドレス))-1, 2)
ここです。**ここがわからないのです。**p152の解説とその中の例題を見ても、「LENGTH」が「文字列の長さを取得する」「文字列の長さで絞込検索をする」ということしかわかりません。
「-1,2」が何を指すのかがわかりません。
もう少し詳しく見てみます。

問題文からすると、ここのコードは「メールアドレスの最後の2文字」を指しているはずです。
この部分だけ見ているとよくわからないので、もう一度SUBSTRINGまで戻ってみます。

p154でこう解説されていました。

SUBSTRING(文字列を表す列,抽出を開始する位置,抽出する文字の数)
⇒抽出された部分文字列

ということは、
「LENGTH(TRIM(メールアドレス))-1」 =抽出を開始する位置
「2」 =抽出する文字の数
ということでしょうか。ここで「2」の意味がわかりました。

あとは「LENGTH(TRIM(メールアドレス))-1」です。「-1」は何を指すのでしょうか?
「抽出を開始する位置」を指しているはずなのですが…
メールアドレスの末尾1文字目を「0」、2文字目を「-1」としているのでしょうか?
p155の例題を見ると「文字列の頭文字を1文字目」として扱っているのだと読み取れますが、
末尾の文字についてはどこにも触れられていませんでした。
見落としているのでしょうか?

「LENGTH -1 関数」等でググってみました。
→目ぼしい記事は見つからず。

本の中から「-」が入った構文を探してみます。
→p156にこんな構文が出てきました。

リスト5-13 百円単位の出金額を取得する

SELECT 出金額, ROUND(出金額, -2) AS 百円単位の出金額
FROM 家計簿

※解説:「これで、出金額の下2桁目、つまり10の位で四捨五入されることになるのよ。」

これだーーーーー!!!
やっとわかりました。
「-1」は「末尾1文字目」という意味だったのですね。
スッキリしました・・・。

文字数を「前から」数えていくのだと思い込んでいました。
「末尾1文字目から 2文字を 抽出する」
なんですね。「後ろから」数えるとのこと。やっとわかりました。

#まとめ
最後に整理します。

CASE SUBSTRING(TRIM(メールアドレス),
               LENGTH(TRIM(メールアドレス))-1, 2)

これは、
①メールアドレスの左右の空白を取り除いて、
②メールアドレスの末尾1文字目から
③2文字目までを
④抽出します
⑤その場合(→次のWHEN~に続く)
という意味だったのですね。

#さいごに
いき詰まっていましたが、Qiitaに書き出しながらひとつひとつを読み解くことで
無事にコードの意味を理解する事が出来ました。
終わってしまえば「なーんだ、そんなこと」なのですが、
記事を書いている最中は本当にわからない状態でした。
まだまだ序盤なのに時間をかけてしまい焦りますが、
ひとつひとつ進めていきたいと思います。

#参考
・書籍『スッキリわかるSQL入門第2版ドリル222問付き!』(インプレス)

#進捗記録
2020/9/15:データベースの学習スタート
2020/9/15~2020/9/21:『マンガでわかるデータベース』オーム社 / 1~4章(Qiita記事2本)
2020/9/22~:『スッキリわかるSQL入門第2版ドリル222問付き!』インプレス

4
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?