WHERE句で条件を指定して抽出したレコード群は、必ずしも意味のある順に並んでいる訳ではありません。ORDER BY句による並べ替えが必要です。
- レコードの順序は不定 -
WHERE句による条件指定で、テーブルから特定のレコードだけを抽出する方法を紹介してきました。しかし、このとき抽出されるレコードの並び順は不定です。「不定」と書くとめちゃくちゃな順序に並んでいるような印象がありますが、そういうことではありません。
レコードは主キーフィールドやインデックス・フィールドの値の順でもなければ、レコードが記録された時系列の順に並んでいる訳でもありません。このことについては、本記事の第3回「レコードの選択と整列~SELECT命令をしっかり理解する」で述べたとおりです。
WHERE句は単に続く条件式を満たすレコードだけを抽出する――厳密に言えば「SELECT命令の抽出対象となるレコードを条件によって限定する」機能を持っているだけであって、抽出されたレコードの並び順は、基本的に元の(テーブルに記録された状態の)ままです。
- 抽出したレコードを並べ替える -
SELECT命令にWHERE句が付け足された場合、条件式で与えている条件を満たすかどうかを調べるために、データベース・エンジンはテーブル内の全レコードを走査します(実際にディスク上のテーブルにアクセスするとは限りません。メモリ内の作業用レコードセットを使う場合もあるでしょう)。
このとき、必ずしも記録されているレコードの先頭(アドレスの低い方)から走査する訳ではありません。データベース・エンジンによっては、現在のカーソル位置から走査を開始するものもあるでしょう。あるいは、与えられた条件やその対象となるフィールドを元に、最も効率的な位置から走査を始めるものもあります。
すると、仮に元のテーブルではレコードが時系列やIDフィールドの値の順に並んでいたとしても、抽出された結果にまでその順序が反映されるとは限らなくなります。多くの場合、抽出結果はIDフィールドの順など一定の意味を持って並んでいますが、それはプログラマーの意図したものではありませんし、それ以後に行う同様の処理で同じ順序が保証されるものでもありません。
従って、WHERE句で条件を与えてレコードを絞り込んだ場合でも、その結果(レコードセット)をORDER BY句で一定の規則によって並べ替えてやる必要があります。
- 並び順を明確に指定する -
WHERE句の条件式とORDER BY句の書式については、これまでの記事を参考にしてください。以下は、WHERE句を使った抽出のみの例です。ORDER BY句は使っていません。
例1)テーブル「商品_mr」から「在庫数が10未満」の商品だけを抽出
SELECT * FROM 商品_mr WHERE 在庫 < 10
先述したように、抽出されたレコードの並び順は不定です。但し、「商品_mr」の「商品ID」フィールドが主キーフィールドに設定されているため、SQL Serverではそのフィールドの昇順に並べ替えられます。これはデータベース・エンジンの仕様であって、他のRDBMSでも必ずこのようになるとは限りません。
また、多くのマスターテーブルは初期段階でIDフィールド(この例では「商品ID」フィールド)の順に入力されるでしょうから、それ以後レコードの追加や削除などが行われていない場合には、テーブル内のレコードもIDフィールドの順に並んでいるのが普通です。そのため、仮にデータベース・エンジンが上述のような仕様でなくても、ORDER BY句を指定せずにSELECT命令で抽出されたレコードがIDフィールドの昇順に並んでいることはあるでしょう。
ただ、何度も繰り返しますが、こういったレコードの自然な並びはあくまでも偶然です。どのような場合でもレコードを意味のある順に並べて取得するためには、プログラマーがORDER BY句によって明確な基準を与えなければなりません。
- WHERE句とORDER BY句の例 -
上記の例にORDER BY句を組み合わせた例を2つ掲げておきます。
例2)テーブル「商品_mr」から「在庫数が10未満」の商品だけを抽出し、在庫数の多い順に並べ替える
SELECT * FROM 商品_mr
WHERE 在庫 < 10 ORDER BY 在庫 DESC
「在庫」フィールドを基準に降順に並べ替えます。WHERE句の条件式に使ったフィールドを、ORDER BY句の整列条件でキーフィールド(整列の基準とするフィールド)にしても構いません。
例3)テーブル「商品_mr」から「在庫数が10未満」の商品だけを抽出し、販売単価の低い順に並べ替える
SELECT * FROM 商品_mr
WHERE 在庫 < 10 ORDER BY 販売単価 ASC
「販売単価」フィールドの値を基準に昇順に並べ替えます。
例4)以下のようにすることも可能です。
SELECT 商品ID, 品名, 在庫 FROM 商品_mr
WHERE 在庫 < 10 ORDER BY 販売単価 ASC
並べ替えの結果は同じですが、「商品ID・品名・在庫」の3つのフィールドだけをレコードセットに取得し、並べ替えのキーとする「販売単価」フィールドは含まれていません。このように、ORDER BY句のキーフィールドを表示しなくても構いません。
|
|
|