Shoeisha Technology Media

資格Zine(しかくジン)

記事種別から探す

SELECT文の使用によるデータの取得 ~ SQLの基本であるSELECT文は、実は難しかった?!

  • LINEで送る
  • このエントリーをはてなブックマークに追加
林 優子[著]
2015/12/15 14:00

 SELECTは、表からデータを取り出し表示するSQLコマンドです。しかし、データベースに格納されているデータを単純に表示しても、わかりづらい/扱いづらいことがあります。実務では、データを出力した後、プログラムやExcelでデータを加工する場合もありますが、ある程度の加工は、データを取り出す時点でやっておいたほうが速いし、その後の扱いも楽だという場合もあります。そんな「技」が試験でも問われるポイントです。

みんなが頭を悩ます「ORDER BY句」の問題

まずは、データ最新の書式や研修の表示順について、確認しましょう。ORDER BY句を指定しない場合の表示順は、何順ですか? 「Oracleがデータを取り出した順」ですよね。だから、どんな順に出てくるか、保証されるものではありません。だから、ORDER BY句をつけて、昇順(小さい順)、降順(大きい順)に並べ替えて表示するのですよね。

それでは、昇順に並べた場合、NULLは先頭に表示されますか? 最後ですか? 降順に並べた場合は?

例1
SQL> SELECT empno,ename,mgr
  2  FROM   emp
  3  WHERE  deptno = 10
  4  ORDER BY mgr;

     EMPNO ENAME             MGR
---------- ---------- ----------
      7934 MILLER           7782
      7782 CLARK            7839
      7839 KING

例1が示すとおり、昇順に並べた場合、NULLは最後(降順に並べた場合は先頭) に表示されます。 しかし、Oracleの仕様がそうであったとしても、みなさんの業務においては、昇順だろうが降順だろうが、NULLを常に先頭に表示したいという要望があるかもしれません。さあ、そういう場合は、どうすればよいのでしょうか。

問1

上司(mgr)が設定されていない従業員を常にリストの先頭に出力する必要があります。どのSQL文を使用しますか。3つ選びなさい。

  • a. SELECT empno,ename,mgr
    FROM emp
    WHERE deptno = 10
    ORDER BY mgr DESC;
  • b. SELECT empno,ename,mgr
    FROM emp
    WHERE deptno = 10<br/ ORDER BY mgr NULLS FIRST;
  • c. SELECT empno,ename,mgr
    FROM emp
    WHERE deptno = 10
    ORDER BY mgr DESC NULLS FIRST;
  • d. SELECT empno,ename,mgr
    FROM emp<br/ WHERE deptno = 10
    ORDER BY mgr DESC NULLS REVERSE;
  • e. SELECT empno,ename,mgr
    FROM emp
    WHERE deptno = 10
    ORDER BY mgr ASC NULLS LAST;

正解は、次の実行例のとおり、abcです。

SQL> -- a
SQL> SELECT empno,ename,mgr
  2  FROM   emp
  3  WHERE  deptno = 10
  4  ORDER BY mgr DESC;

     EMPNO ENAME             MGR
---------- ---------- ----------
      7839 KING
      7782 CLARK            7839
      7934 MILLER           7782

SQL> -- b
SQL> SELECT empno,ename,mgr
  2  FROM   emp
  3  WHERE  deptno = 10
  4  ORDER BY mgr NULLS FIRST;

     EMPNO ENAME             MGR
---------- ---------- ----------
      7839 KING
      7934 MILLER           7782
      7782 CLARK            7839

SQL> -- c
SQL> SELECT empno,ename,mgr
  2  FROM   emp
  3  WHERE  deptno = 10
  4  ORDER BY mgr DESC NULLS FIRST;

     EMPNO ENAME             MGR
---------- ---------- ----------
      7839 KING
      7782 CLARK            7839
      7934 MILLER           7782

SQL> -- d
SQL> SELECT empno,ename,mgr
  2  FROM   emp
  3  WHERE  deptno = 10
  4  ORDER BY mgr DESC NULLS REVERSE;
ORDER BY mgr DESC NULLS REVERSE
                        *
行4でエラーが発生しました。:
ORA-00905: キーワードがありません。


SQL> -- e
SQL> SELECT empno,ename,mgr
  2  FROM   emp
  3  WHERE  deptno = 10
  4  ORDER BY mgr ASC NULLS LAST;

     EMPNO ENAME             MGR
---------- ---------- ----------
      7934 MILLER           7782
      7782 CLARK            7839
      7839 KING

ORDER BY句には、もう1つ便利な機能があります。 指定した件数分表示する機能です。

問2

emp表の中で給与が高い順に表示します。ただし、表示する行は3件のみとします。 どのSQL文を使用しますか。

  • a. SELECT ename,sal FROM emp
    WHERE ROWNUM <= 3
    ORDER BY sal DESC;
  • b. SELECT ename,sal FROM emp
    ORDER BY sal DESC FETCH FIRST 3 ROWS ONLY;
  • c. SELECT ename,sal FROM emp
    ORDER BY sal DESC FETCH FIRST 3 ROWS WITH TIES;
  • d.SELECT ename,sal FROM emp
    ORDER BY sal ASC FETCH LAST 3 ROWS ONLY;

正解は、次の実行例のとおり、bです。

SQL> -- a
SQL> SELECT ename,sal FROM emp
  2  WHERE ROWNUM <= 3
  3  ORDER  BY sal DESC;

ENAME             SAL
---------- ----------
ALLEN            1600
WARD             1250
SMITH             800

SQL> -- b
SQL> SELECT ename,sal FROM emp
  2  ORDER  BY sal DESC FETCH FIRST 3 ROWS ONLY;

ENAME             SAL
---------- ----------
KING             5000
MILLER           4900
SCOTT            3000

SQL> -- c
SQL> SELECT ename,sal FROM emp
  2  ORDER  BY sal DESC FETCH FIRST 3 ROWS WITH TIES;

ENAME             SAL
---------- ----------
KING             5000
MILLER           4900
SCOTT            3000
FORD             3000

SQL> -- d
SQL> SELECT ename,sal FROM emp
  2  ORDER  BY sal ASC FETCH LAST 3 ROWS ONLY;
ORDER  BY sal ASC FETCH LAST 3 ROWS ONLY
                        *
行2でエラーが発生しました。:
ORA-00905: キーワードがありません。

FETCH FIRSTキーワードを使用して、戻される行の数または割合を指定できます。 ただし、FETCH LASTというキーワードは存在しないので、ご注意ください。

件数を表示するときにはROWS、割合のときはPERCENTを使用します。今回は3件と指定があったので、3 ROWSです。10%と指定された場合は、10 PERCENTと書きます。

実行例からわかるように、給与の多い順に並べると3番目の金額は、実は3000なのですが、同じ金額の人が2人います。順位的に表現すると、同額3位ってことですね。

しかし、設問では「3件のみ」と要求されていたので、ONLYを使用します。「行制限している最後の行」と同じ値が連続していて、その行も表示する場合はWITH TIESを使用します。

あ、aを選択したあなた。Oracle経験が長いですね。 OracleがFETCH FIRSTキーワードをサポートするまでは、ROWNUM疑似列を使用して、限定何件を表示するというSQL文を(副問合せなどを駆使して)書くこともありました。私にも経験あります(苦笑)。 しかし、もうそんなことをする必要はないのです。おぼえておきましょうね。

ちなみに、5件スキップして、6件目から3件表示するということができるOFFSETというキーワードもありますから、復習しておいてください。

もし、資格を取得済みの先輩方が、後輩指導のためにと思ってこの連載を読んでくださっているのなら、SQLとはいえ、最新の書籍や研修で知識/技術を身につけるよう指導してあげてください。 今まで苦労していたことが、キーワード1つで簡単にできるようになっているかもしれません。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 林 優子(ハヤシ ユウコ)

    日本オラクル株式会社の教育ビジネスのスタートアップを全面的に支援し、バージョン5の頃からOracleに携わるベテラン講師として知る人も多い。Oracle認定講師を表彰するExcellent Instructorを連続受賞。1ランク上のITスペシャリスト育成を目標に、データベース分野にとどまらず「プレゼンテーション」、「ロジカルシンキング」などのトレーニングも手がけている。著書に『オラクルマスター教科書』シリーズ(翔泳社)、『プロとしてのデータモデリング入門』(SBクリエイティブ)など。その他、雑誌執筆、著書・メディア出演も多数。

バックナンバー

連載:めざせオラクルマスターホルダー! Oracle DB 12c SQL基礎 弱点克服スクール

もっと読む

この記事もオススメ

All contents copyright © 2015-2017 Shoeisha Co., Ltd. All rights reserved. ver.1.0