【SQLを丁寧に理解する】ROWNUM と ORDER BY ~PART2:SQLの実行順序~
こんにちは、EightyEightRiceです。
今日の記事は、【SQLを丁寧に理解する】ROWNUM と ORDER BY ~PART2:SQLの実行順序~ です。
データベースを扱い場合に、よくハマってしまう項目について、丁寧に説明していきます。
ざっと読み飛ばすだけでも、
「へぇーそうなんだ」
と、思っていただけるような構成を心がけています。
今回は
ROWNUM と ORDER BY ~PART2:SQLの実行順序~
です。
こんな話を聞いた事はありませんか?
「ROWNUMとORDER BY を一緒に使ってはいけない」
結論は、「ROWNUMとORDER BYは、一緒に使って良い場合と悪い場合がある」です。
あるSQLの結果に対して、
ORDER BY でソートして、WHERE句で「ROWNUM = 1」のような使い方
は、かなり危険です。
しっかりと理解する為に、以下の2つのポイントに分けて解説していきます。
・ROWNUMとは
・SQLの実行順序
前回(PART1)では、ROWNUMについて解説しました。
今回はSQLの実行順序と、なぜ
”「ROWNUM = 1」のような使い方は、かなり危険”
なのか解説します。
実行順序について、今回は特にSELECT文について考えます。
基本的な句として、まず、
SELECT、FROM、WHEREがあります。つぎにオプション的な句として、
JOIN、GROUP BY 、ORDER BY 、HAVING などがあります。
これらの句は実行される順序が決まっています。
(あるSQLはSELECTから実行、またあるSQLはFROM句から実行とはなりません。)
SELECT文の句は以下の順序で実行されます。
1. FROM
2. JOIN
3. WHERE
4. GROUP BY
5. HAVING
6. SELECT
7. ORDER BY
※今回の記事に影響のない句(ONやLIMIT、DISTINCTなど)は省略しています
この実行順序をもとに以下のSELECT文の動作を考えてみます。
SELECT
社員コード
, 生年月日
, ROWNUM
FRON
社員表
WHERE
ROWNUM = 1
ORDER BY
生年月日
生年月日の昇順に並べて、一番若い社員をSELECTしようとしています。
ただ、これが危険なSQLです。
なぜでしょうか。
ROWNUMは、FROMとWHEREから抽出された行に対して1から重複しない連番を付番します。
WHERE句にROWNUM = 1 とすると、結果的に1行目の行が抽出されます。
一見正しい結果が得られそうですが、ここで注意したいのは、ORDER BY の実行順序が最後になっている点です。
サンプルのSELECT文のように、
WHERE
ROWNUM = 1
ORDER BY
生年月日
とすると、1行抽出した後に、生年月日でソートになってしまいます。
WHERE句で絞られたデータを取り出す順にROWNUMが付番されるますが、
取り出す順序はデータベースエンジンに依存するので、どの行から抽出されるかはわかりません。
1番若い社員を抽出するには不適切なSQLの使い方と言えます。
今回解説したポイント
ORDER BY でソートして、WHERE句で「ROWNUM = 1」の注意点
「単純に条件を満たすデータを1件抽出する場合」
➡ OK
「ある列を指定して並べ替えたものから最小(最大)のデータを抽出する場合」
➡ NG
以上、解説でした。
/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_
SQLについて質問があれば随時募集しています。
ご遠慮なくお問い合わせください.
/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_