問題18425について

  • フォーラムは新サイトへ移行しました。
  • このフォーラムではゲスト投稿が禁止されています
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 .2 .3 | 投稿日時 2015-9-17 5:20
abcde12345  新米   投稿数: 2
下記の問題の答えで「LEDライト」「led light」が答えに含まれない理由がよくわかりません。
わかる方ご教示願えませんか

次のSQL文を実行して表示される製品名として正しいものはどれですか(該当するものを全て選択して下さい)。

 SELECT prod_name
 FROM products
 WHERE UPPER(prod_name) BETWEEN 'H' AND 'LE';

○ HighPower_LED_ハンディライト2
○ Lantern
LEDライト
led light
(Wide)LEDシーリングライト
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2015-9-17 10:02 | 最終変更
arashi1977  長老 居住地: 広島  投稿数: 1715
うーん、ちょっと解説がよわいのかなぁ…

以下の公式情報を見てください。
Oracle® Database SQL言語リファレンス 11g リリース2 (11.2) B56299-07:BETWEEN条件
http://docs.oracle.com/cd/E16338_01/server.112/b56299/conditions011.htm

真ん中あたりの説明を確認します。
引用:
さらに次の式の値について考えてみます。

expr1 BETWEEN expr2 AND expr3
この式の値は次のブール式の値と同じです。

expr2 <= expr1 AND expr1 <= expr3
expr1 BETWEEN expr2 AND expr3 は「expr1がexpr2とexpr3の間のもの」ではなく「expr1がexpr2以上、かつ、expr1がexpr3以下のもの」です。

標準的なSQLなので、sqliteで確認してみました。

まず、expr1 >= expr2のパターン
sqlite> select prod_name from products where upper(prod_name) >= 'H' order by upper(prod_name);
HighPower_LED_ハンディライト2 ←ここ
Lantern ←ここ
led light
LED_サイクルライト
LEDライト
ledランタン
Light_LED_ハンディライト(6球)
Silver LED_ライト
Watch1
watch2
watch3

次に、expr1 <= expr3のパターン
sqlite> select prod_name from products where upper(prod_name) <= 'LE' order by upper(prod_name);
(Wide)LEDシーリングライト
BEST HITS_60's
BEST HITS_70's
BEST HITS_70's DANCE
BEST HITS_80's
BEST HITS_80's DANCE
cyclelight
HighPower_LED_ハンディライト2 ←ここ
Lantern ←ここ
「LE(大文字LE、ASCIIコード10進数表記で76+69=145)」以下のものが表示されています。
※「LED(大文字LED、ASCIIコード10進数表記で76+69+68=213)」だとLEより大きくなるので含まれない。LIKE演算子とは異なるので注意してください。

検証には以下のSQLを使ってみるといいですよ
SELECT 'LE' <= 'LE';
SELECT 'LED' <=  'LE';
SELECT 'LED' LIKE 'LE';
SELECT 'LED' LIKE 'LE%';

なので、この結果のAND(両方の結果に存在するもの)は
sqlite> select prod_name from products where upper(prod_name) between 'H' and 'LE';
HighPower_LED_ハンディライト2
Lantern
になるということです。
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2015-9-19 10:33
abcde12345  新米   投稿数: 2
解説ありがとうございます。

下記の文言で理解できました。
BETWEENをLIKEの感覚でとらえており先頭文字がHから始まって先頭LEで終わる文字と解釈しておりました。

#############################################################
「LE(大文字LE、ASCIIコード10進数表記で76+69=145)」以下のものが表示されています。
※「LED(大文字LED、ASCIIコード10進数表記で76+69+68=213)」だとLEより大きくなるので含まれない。LIKE演算子とは異なるので注意してください。
#############################################################
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2015-12-13 10:48
pico1  新米   投稿数: 2
比較対象の範囲 UPPER(prod_name)がよくわかりません;;
LIKEではなく、文字をASCIIコード10進数表記で比較することは理解できるのですが…どこからどこまでをASCIIコード10進数表記で変換した値を、H〜LEのASCIIコード10進数表記の範囲で絞り込むのかがよくわかりません。。先頭文字なのか先頭の単語なのか商品名全体なのか、どこから読み取ればいいのでしょうか?
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2015-12-13 17:57 | 最終変更
arashi1977  長老 居住地: 広島  投稿数: 1715
ここを読んでみてください。

Oracle® Database SQL言語リファレンス
11gリリース2 (11.2)
データ型の比較規則
https://docs.oracle.com/cd/E16338_01/server.112/b56299/sql_elements002.htm

ここの文字列比較の「空白埋め比較セマンティクスおよび非空白埋め比較セマンティクス」から引用します。
引用:
空白埋め比較セマンティクスでは、2つの値の長さが異なる場合、Oracleはまず短い方の値の最後に空白を追加して、2つの値が同じ長さになるようにします。次に、その2つの値を、最初に異なる文字まで1文字ずつ比較します。最初に異なる文字の位置で、大きい方の文字を持つ値の方が大きいとみなされます。
(略)
非空白埋め比較セマンティクスでは、Oracleは、2つの値を、最初に異なる文字まで1文字ずつ比較します。最初に異なる文字の位置で、大きい方の文字を持つ値の方が大きいとみなされます
てことで、
引用:
先頭文字なのか先頭の単語なのか商品名全体なのか
上記の通り、比較に使う文字列であるUPPER(prod_name)と、比較対象である「H」または「LE」を先頭から順に比較、ですね。

なので、以前の私の投稿にある
・select prod_name from products where upper(prod_name) >= 'H' order by upper(prod_name);
・select prod_name from products where upper(prod_name) <= 'LE' order by upper(prod_name);
のような結果になるわけですね

まぁバイナリ比較または言語比較からしても
引用:
デフォルトのバイナリ比較では、Oracleは、データベース・キャラクタ・セット内の文字の数値コードを連結した値に従って文字列を比較します。第1の文字の数値が第2の文字の数値よりも大きい場合、第1の文字は第2の文字よりも大きいとみなされます。
なので、順にみるというのは同じかと思います。
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2015-12-19 11:02
pico1  新米   投稿数: 2
解説ありがとうございました。すっきりしました。
確認が遅れて申し訳ありません、12Cの投稿記事をずっとさがしてました;;

  >フォーラム検索へ


Copyright (c) 2020 Ping-t All rights reserved.