連載
» 2005年06月10日 00時00分 公開

ORACLE MASTER Bronze SQL基礎I 講座(2):SQL問い合わせによる行の制限とソート

Oracleデータベースエンジニアとしての実力を証明するORACLE MASTER資格。その入り口であるBronze資格の取得は難しくない。本連載と、同時掲載中の連載「Bronze DBA講座」で合格を目指そう!(参考記事:「Oracle 10g対応のORACLE MASTERとは?」)

[有限会社 G.F.インフィニティ (Project - ∞)]

 前回「Oracleで使うSQLの基礎を学ぶ」で、SELECT文の基本的な機能を紹介しました。今回は、SELECT文による行の制限とソートを学びましょう。

理解しておきたいこと

1. 確認しておきたい内容

  • 問い合わせによって取得される行の制限
  • 問い合わせによって取得される行のソート

2. WHERE句による行の制限WHERE句による行の制限

 問い合わせの行を制限するには、SELECT文でFROM句の直後にWHERE句を使用します。

SELECT {* | [DISTINCT] 列名 | 式} [列別名] [,...]
FROM 表名
WHERE 条件式;
WHERE   行を制限することの宣言
条件式  {列名 | 定数} 比較条件 {列名 | 定数 | 値リスト}

例:

SQL> SELECT empno, ename FROM emp WHERE empno = 7900;

EMPNO ENAME

---------- ----------

7900 JAMES

 比較条件として使用できる演算子には、次のものがあります。

演算子 説明
= 等しい(左側と右側が等しい)
> より大きい(左側が右側より大きい)
>= 以上(左側と右側が等しいか、左側が右側より大きい)
< より小さい(左側が右側より小さい)
<= 以下(左側と右側が等しいか、左側が右側より小さい)
<>、!=、^= 等しくない(左側と右側が等しくない)
BETWEEN .... AND .... 2つの値の間(2つの値は最小値、最大値の順に記述し、その値も含む)
IN (値リスト) 値リストのいずれかと等しい
LIKE パターン パターンと等しい
IS NULL NULLと等しい
表1 演算子とその意味

 <=と>=を記述するときは、=記号は必ず右側にきますので注意しましょう。また、NULLの場合は、「= NULL」としてもエラーにはなりませんが、結果は戻りません。よって「IS NULL」を使用するということに注意しましょう。

問題

問題1

次のデータと要件を確認してください。

EMPNO ENAME   SAL     COMM
----- ------- ------- -------
7369  SMITH   800
7499  ALLEN   1600    300
7521  WARD    1250    500
7566  JONES   2975
  • SALとCOMMを計算した結果を表示する
  • COMMが0の行を表示しない
  • COMMがNULLの場合は0とする

次の文を実行したとき、上記の要件を満たすものはいくつありますか?

SELECT empno, sal*comm FROM emp WHERE comm IS NOT NULL;

a. 1つ
b. 2つ
c. 3つ
d. エラーとなる

正解:a

解説

 問題のSELECT文では、「COMMがNULLでない行のSALとCOMMの計算結果を表示する」という結果が戻ります。問題の要件に挙げている要素を満たすには次のことが必要です。

●SALとCOMMを計算した結果を表示する

問題のSELECT文で満たされます。ただし、NULL値を含む式を計算した場合は、計算結果は必ずNULLとなります。

●COMMが0の行を表示しない

「WHERE comm > 0」といった条件が必要です。問題のSELECT文では記述されていないためこの要件は満たされません。

●COMMがNULLの場合は0とする

「NVL(comm, 0)」というようにNVL関数を使用してNULL値を置き換える必要があります。問題のSELECT文ではWHERE句で「comm IS NOT NULL」としたため、COMMがNULLの行が問い合わせ結果に含まれず、この要件は満たされません。

問題2

次の文を確認してください。

SELECT empno, ename FROM emp WHERE comm = NULL;

この文の結果に関する説明として正しいものを選択しなさい。

a. COMMがNULLのレコードが戻される
b. エラーとなる
c. レコードは戻されない
d. すべてのレコードが戻される

正解:c

解説

 NULL値を検索するには「IS NULL」演算子が必要です。NULL値は値が不明・未割り当てな状態です。空白や「0」とも異なります。上記の文のように「= NULL」とした場合、エラーにはなりませんが、いずれとも等しくないため、レコードは戻されません。

問題3

従業員の職種に“SA_”が含まれている行を取り出している問い合わせを選択しなさい。

SELECT empno, ename FROM emp WHERE comm = NULL;

a. SELECT empno, ename FROM emp WHERE job = '%SA_%';
b. SELECT empno, ename FROM emp WHERE job LIKE '%SA\_%' ESCAPE '\';
c. SELECT empno, ename FROM emp WHERE job LIKE "%SA_\%" ESCAPE "\";
d. SELECT empno, ename FROM emp WHERE job LIKE '%SA_\%';
e. SELECT empno, ename FROM emp WHERE job = 'SA_';

正解:b

解説

 前回の宿題にした問題です。LIKEキーワードによる文字パターンに一致するかどうかの条件では、「%(0以上の任意の文字の連続)」と「_(任意の1文字)」がワイルドカードになっています。これらのワイルドカードを値として一致させる場合には「ESCAPE」キーワードを使用してエスケープ記号を指定し、ワイルドカードの前に置く必要があります。

WHERE 列名 LIKE '文字パターン' ESCAPE 'エスケープ記号'

 今回の問題のように「SA_」で始まるということは、「_」を文字として認識させる必要があります。エスケープ記号を「\」とし、「\_」と指定することで、「_」を文字として認識させています。エスケープ記号は、任意の文字です。文字パターンに含まれないもの(/、$など)を使用するとよいでしょう。

 選択肢cのように二重引用符で囲むことはできませんので注意しましょう。

問題4

次のCUST表の定義を確認してください。

CUST_ID       NOT NULL    NUMBER(6)
CUST_NAME     NOT NULL    VARCHAR2(20)
CUST_ADDRESS              VARCHAR2(20)
COUNTRY_ADDRESS           VARCHAR2(20)
CREDIT_LIMIT              NUMBER(9,2)

現在住んでいる国(COUNTRY_ADDRESS)が、フランスである顧客を求めている文を選択しなさい。

a. SELECT cust_id, cust_name FROM cust WHERE LOWER(country_address) = "france"
b. SELECT cust_id, cust_name FROM cust WHERE LOWER(country_address) IS 'france'
c. SELECT cust_id, cust_name FROM cust WHERE LOWER(country_address) LIKE "france"
d. SELECT cust_id, cust_name FROM cust WHERE LOWER(country_address) LIKE 'france'
e. SELECT cust_id, cust_name FROM cust WHERE LOWER(country_address) = '%france%'

正解:d

解説

 本来LIKE演算子は文字のパターンマッチのために使用しますが、この問題の「国がフランス」である行を取得できるのは、正解dの文だけです。文字パターンとしての「_」または「%」を使用していないため、このWHERE句は「LOWER(country_address) = 'france'」として動作します。

 選択肢eは、一見正しいように見えますが、LIKE演算子ではなく「=」で比較しているため、「%france%」という文字が格納されている行を問い合わせしています。

3. AND、OR、NOTによる論理条件

 WHERE句で記述する条件式は、真(TRUE)であると判断された行だけを戻します。WHERE句では、単一の条件式だけでなく、AND、OR、NOTを使用することで条件式を連結することができます。

演算子 説明
AND 2つの条件式がともにTRUEを戻すときにTRUEとなる
OR 2つの条件式のいずれかがTRUEを戻すときにTRUEとなる
NOT その条件でない場合にTRUEとなる

 複数の条件があるときは、条件の優先順位に従って処理が行われます。条件式内での優先順位は次のとおりです。

優先順位 条件式
1 SQL演算子(算術演算子(+、-、*、/)、連結演算子(||)など)
2 比較条件(=、<、<=、>、>=、<>、!=、^=)
3 IS NULL、IS NOT NULL、LIKE、IN、NOT IN
4 BETWEEN、NOT BETWEEN
5 NOT論理条件
6 AND論理条件
7 OR論理条件

 なお、算術演算子は、「*(乗算)、/(除算)」が先に計算され、「+(加算)、-(減算)」が後に計算されます。これらの優先順位を変更する場合は、「()」を使用します。()で囲まれた条件式は先に処理が行われます。

4. ORDER BY句による行のソート

 問い合わせの行をソートして戻すには、SELECT文の最後にORDER BY句を使用します。

SELECT {* | [DISTINCT] 列名 | 式} [列別名] [,...]
FROM 表名
[WHERE 条件式]
ORDER BY {列名 | 式 | 列別名 | 列位置}[,...] [ASC | DESC];
ORDER BY  行をソートすることの宣言
ASC       行を昇順ソートする(デフォルト)
DESC      行を降順ソートする

 「列位置」とは、SELECT句の列指定の順に付けた1、2といった番号です。「*」を使用している場合は、表の列定義順に番号が割り当てられます。また、ORDER BY句では、SELECT句の列に付けた列別名も使用できることに注意しましょう。

例:

SQL> SELECT empno, ename, sal FROM emp WHERE deptno=10 ORDER BY 3 DESC;

EMPNO ENAME SAL

---------- ---------- ----------

7839 KING 5000

7782 CLARK 2450

7934 MILLER 1300

 複数の列をソート列に指定した場合は、最初に指定したソート列でまずはソートし、最初の列の値が同じものが、2番目に指定したソート列でソートされます。ASCとDESCの指定は、指定した列にのみ影響するので注意しましょう。

 データ型の違いによるソートの基準は、次のとおりです。

データタイプ 昇順ソート 降順ソート
数値データ 小さい値から順に表示
(例:1、2、3、……)
大きい値から順に表示
(例:99、98、97、……)
日付データ 古い日付から順に表示
(例:2005/01/01、2005/01/02、……)
新しい日付から順に表示
(例:2005/12/31、2005/12/30、……)
文字データ アルファベット順に表示
(例:A、B、……、Z、a、b、……、z)
アルファベットの逆順に表示
(例:z、y、…a、Z、Y、…A)
NULL値 最後に表示 最初に表示

問題

問題1

次の2つの文を確認してください。

SELECT empno, sal FROM emp ORDER BY sal DESC;
SELECT empno, sal FROM emp ORDER BY 2 DESC;

この2つのSELECT文に関する説明として正しいものを選択しなさい。

a. 2つ目の文はempno、salの順にソートが行われる
b. 2つ目の文にsalという別名を指定すると2つの文は同じ結果を表示する
c. 2つ目の文は構文エラーとなる
d. 2つの文は同じ結果を表示する

正解:d

解説

 ORDER BY句によるソートは、列名、列別名、列位置のいずれかで指定できます。この問題のsal列の指定は、SELECT句で2番目ですから、「ORDER BY 2」とするのも同じことを指定しています。

 選択肢aのempno、salの順にソートを行うには、「ORDER BY 1, 2」と指定する必要があります。

問題2

次の文を確認してください。

SELECT ename, hiredate HIRE_DATE FROM emp ORDER BY hiredate DESC;

この文の結果の説明として正しいものを選択しなさい。

a. 日付はデフォルトで大きい順に並ぶため、DESCキーワードは不要
b. 実行時にエラーとなる
c. 正しくhiredate列で降順にソートされて表示される
d. HIRE_DATE別名を指定すれば、正しく降順ソートされて表示される

正解:c

解説

 ORDER BY句によるソートは、ASCを付けなくても昇順ソートがデフォルトです。DESCを付けることで降順ソートになります。また、ORDER BY句で指定する列は、列名、列別名、列位置のいずれかを指定できます。

問題3

ORDER BY句によるソート処理のデフォルト動作として正しいものを2つ選択しなさい。

a. 昇順にソートされる
b. NULL値は最初に表示される
c. アルファベットはZ-Aの順に表示される
d. 日付は古いものから表示される。

正解:a,d

解説

 ORDER BY句によるデフォルトのソート処理には、次の特徴があります。

  • 昇順ソート(ASC)
  • NULL値は最後に表示される
  • アルファベットはA-Zの順に表示される
  • 数値は小さい値から表示される
  • 日付データは古い値から表示される

 NULL値は、降順ソート(DESC)を使用した場合は、最初に表示されます。NULL値はほかの値より大きい値として扱われますので注意しましょう。

問題4

給与(sal)の高い順にデータを表示している文を選択しなさい。

a. SELECT ename FROM employees ORDER BY sal DESC;
b. SELECT ename FROM employees ORDER BY sal;
c. SELECT ename FROM employees SORT ORDER BY sal DESC;
d. SELECT ename FROM employees SORT ORDER BY sal;

正解:a

解説

 ソートしてデータを表示するには、ORDER BY句を使用します。ORDER BYで指定する列には、次のソート順序を指定できます。

  • ASC :昇順(小さい値から)。デフォルト
  • DESC :降順(大きい値から)

問題にある「給与の高い順」にするには、DESCキーワードが必要です。

まとめ

 次の内容をチェックしておきましょう。

  • NULL値を検索するには、「IS NULL」が必要
  • LIKEを使用する場合、ワイルドカード(_、%)を文字として扱うには、ESCAPE句が必要
  • ORDER BY句では、列名、列別名、列位置のいずれかで指定できる
  • ORDER BY句では、デフォルトは昇順ソート(小さい順)

宿題

 次回は、「単一行関数」を確認します。次の宿題を解いておいてください。

次の問い合わせ結果として正しいものを選択しなさい。

SELECT TRUNC(ROUND(MOD(1600, 10), -1), 2) FROM dual;

a. 0
b. 1
c. 0.00
d. エラーとなる

IT資格試験の模擬問題をWebベースで学習できる@IT自分戦略研究所の新サービス「@IT資格攻略」では、Oracle関連の資格をテーマとして取り上げています。Bronze SQL 基礎 I、Bronze DBA 10gも近日中に追加予定です。「無料お試し版」もありますので、記事と併せてご覧ください。



Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。