前回からSQL編に入っている。
まずは、SQL自体の説明と、SELECT文の基本的な書き方を解説した。
SELECT文の書き方は今回以降も使うので、先に理解しておこう。
以下がその記事だ。
【PHP講座14】SQL編1 -SELECT文の基本- | Shino’s Mind Archive
さて、今回も引き続きSELECT文の解説を行う。
今回は、前回の内容で持ってきた結果に対して、以下二つの操作を行う方法を解説しよう。
- 並び替え
- 表示件数の絞り込み
特に並び替えはよく使うので、しっかり身に付けていきたい。
SELECT結果の並び替えを行うORDER BY句
まずは並び替えから。
構文を先に紹介しよう。
SELECT 列名 FROM テーブル名 (WHERE 条件) ORDER BY 列名 [ASC|DESC];
注目して欲しいのは、後ろの方についているORDER BY
という部分。
これが、並び替えを行うためにつけるものだ。
ORDER BY 列名
で、ソートする列名を指定する。
すると、結果として得られる表のデータが、その列の昇順でソートされた形で出てくる。
基本的には、これだけだ。
例えば、前回作ったproductテーブルの情報を、値段の安い順に取得したい場合は、
SELECT * FROM product ORDER BY price;
としてあげれば取得できる。
さて、構文では後ろに[ASC|DESC]
とついている。
これは、ASC
、もしくはDESC
をつけることもできることを表している。
列名の後ろにこのどちらかをつけることができ、ASC
の場合は昇順、DESC
の場合は降順に並び替えが行われる。
上の例で、最後のpriceのさらに後ろにDESC
とつけてみよう。
SELECT * FROM product ORDER BY price DESC;
今度は、値段の高い順に表示されたはずだ。
さて、ここでもう一段階深掘りをしよう。
今回の例でもあるのだが、このソートを行う対象の列に、複数全く同じデータがあった場合だ。
このとき、何も指定しないと、そのままデータが入った順が保持される。
ここまでの例では、両方とも値段が120円の「缶コーヒー」、「オレンジジュース」がこの順番で出てきたと思う。
さて、こういった場合に、その中だけで並び変えをしたいとしよう。
つまり、大元のデータは列Aでソートするが、同じデータがあった場合に、それらのデータを今度は列Bの値で並び替えたい、という場合。
これも可能だ。
そのとき、ORDER BY句で指定する列を増やす。
SELECT 列名 FROM テーブル名 (WHERE 条件) ORDER BY 列1 [ASC|DESC], 列2 [ASC|DESC];
このように書くことで、まずは列1でのソートが行われる。
その上で、列1の同じデータ内で、更に列2によるソートが行われる。
ちょっと分かりづらいと思うので、表で詳しく見ていこう。
今、productテーブルは以下のようになっている。
id | name | price | stock |
---|---|---|---|
1 | 缶コーヒー | 120 | 20 |
2 | オレンジジュース | 120 | 15 |
3 | コーラ | 130 | 20 |
4 | お茶 | 110 | 10 |
5 | 水 | 90 | 12 |
さて、これに対し、以下のSQLを実行してみよう。
SELECT * FROM product ORDER BY price ASC, stock ASC;
このときの、並び替えの様子を順番にお見せしよう。
まず、並び替え前の状態は、上に示した通りだ。
SELECT
の直後に全列を持ってくる*
を指定し、条件を指定していないので全行を持ってきている。
そして、まずは一つ目のORDER BY句でpriceのASC…昇順で並び替える。
この状態では、priceが同じものに関しては元の状態を保持する。
つまり、以下のようになる。
id | name | price | stock |
---|---|---|---|
5 | 水 | 90 | 12 |
4 | お茶 | 110 | 10 |
1 | 缶コーヒー | 120 | 20 |
2 | オレンジジュース | 120 | 15 |
3 | コーラ | 130 | 20 |
ここで、priceが120であるような行が二つあることに注目してほしい。
現時点で、ここのデータは元のテーブルの並びを保持している。
これを、更にstockの昇順で並び替えるのだ。
今、缶コーヒーの20よりもオレンジジュースの15の方が小さいので、ここの順番が入れ替わる。
よって、最終的に以下のような形で結果が得られるのだ。
id | name | price | stock |
---|---|---|---|
5 | 水 | 90 | 12 |
4 | お茶 | 110 | 10 |
2 | オレンジジュース | 120 | 15 |
1 | 缶コーヒー | 120 | 20 |
3 | コーラ | 130 | 20 |
このように、並び替えも色々と工夫ができるようになっている。
PHP側で取得した後にあれこれ操作しなくて済むよう、データの並びにも気を付けよう。
ちなみに、表示していない列で並び替えを行うことも可能だ。
どういうことかというと、例えば値段が安い順に、その商品名だけを表示する、ということも可能ということ。
実際に、以下のSQLで実現可能だ。
SELECT name FROM product ORDER BY price;
このように、表示しない列での並び替えも可能なので覚えておこう。
SELECT結果の表示件数を絞るLIMIT句
さて、今回はもう一つ紹介を。
見出しの通りだが、SELECTの結果を制限することができる。
構文は以下。
SELECT 列名 FROM テーブル名 (WHERE 条件) (ORDER BY 列名) LIMIT 件数;
また一番最後に新しくくっついている。
ここが、表示件数を絞ることのできるLIMIT句になる。
結果がここに指定した数以上の行数になった場合、上からその数になるまで抜き出してくれるのだ。
例えば、結果が100件になるようなSQLでこのLIMITに10を指定した場合、上から10件だけを持ってきてくれる。
なお、LIMITの数字より元々の結果が少ない場合は、全データが表示される。
結果が10件でLIMITに15を指定していたら、10件全てが出てくるというわけだ。
エラー等にはならないので、安心してほしい。
今回の例で試してみよう。
まず、productテーブルをそのまま、3件だけ表示してみる。
SELECT * FROM product LIMIT 3;
これを実行すると、「缶コーヒー」、「オレンジジュース」、「コーラ」の行が抜き出されて表示される。
また、当然だがORDER BY句などと組み合わせることも可能だ。
今度は、値段が一番高いものだけを表示してみよう。
SELECT * FROM product ORDER BY price DESC LIMIT 1;
こうすると、今度は「コーラ」だけが表示されるはずだ。
ここまでのまとめ
さて、前回からSELECT文について色々と解説してきた。
ここまでの内容を振り返ってみよう。
まず、構文は以下の通り。
SELECT 表示列名 FROM テーブル名 (WHERE 条件) (ORDER BY ソート列名 [ASC|DESC]) (LIMIT 件数);
小括弧は一つのまとまりで、あってもなくてもいい。
これで、表示までの処理は以下のようになっている。
- テーブル名で指定されているテーブルに注目する
- WHEREがあったら、条件で行を絞り込む
- 表示列名にある列を持ってくる
- ORDER BYがあったら、その列でソートを行う
ASCなら昇順、DESCなら降順、どちらもなければ昇順 - LIMITがあったら、その数字分だけ上から抜き出す
基本的に、上から順番に処理していると思ってもらっていい。
例えば、WHEREとLIMITがあったら、まずWHEREで条件を絞り込み、そのあとLIMITで表示件数の絞り込みが行われる。
こういった細かい順番の違いでも結果が変わってくることがあるので、しっかり動き方をマスターしておこう。
おわりに
今回は、主にSELECTで持ってきた結果のソート、あるいは表示件数の制限をする方法を解説した。
どちらも、そこそこに使えるので、動き方含めてしっかり理解しておこう。
さて、次回はグループ化というものを解説する。
ここから一気に難易度が上がるので、落ち着いて進めていこう。
なお、今回はオマケ付きだ。
結果として表示する列名を変更する方法についてサクッと解説する。
現段階ではそんなに重要ではないが、いずれあった方がいいので、先に解説してしまおう。
オマケ:結果における列名の変更
というわけで、オマケだ。
これまで、実行してきた結果はそのまま元のテーブルで定義されていた列名で表示されていた。
この列名を、結果を表示するときだけ変更する方法がある。
SELECT 列名 AS 変更列名 FROM テーブル名;
表示する列名の後ろにAS
を挟んで表示させたい列名を書く。
そうすることで、結果表示するときだけその名前に変更することができるのだ。
例えば、以下のように実行してみよう。
SELECT name AS '商品名' FROM product;
こうすると、普通にname列の内容が表示されるのだが、その列名に注目してみよう。
ASの部分が無かった時は「name」となっていたと思うが、今回は「商品名」に変わっていると思う。
このように、列名を変えることができる。
もちろん、元のテーブルには影響はないので、一時的に変えたい場合に有効だ。
ちなみに、ORDER BYでこの変更後の列名を使うことも可能。
ただし、WHERE句では使うことができない。
これは、処理の順番を考えると分かりやすい。
処理の順番を再掲しよう。
- テーブル名で指定されているテーブルに注目する
- WHEREがあったら、条件で行を絞り込む
- 表示列名にある列を持ってくる
- ORDER BYがあったら、その列でソートを行う
ASCなら昇順、DESCなら降順、どちらもなければ昇順 - LIMITがあったら、その数字分だけ上から抜き出す
この別名をつける処理は、上の3つ目で行われている。
WHEREはそれよりも前の処理なので、別名がまだ読み込まれておらず、使えない。
ORDER BYはそれよりも後の処理なので、もう別名が読み込まれていて、使える。
とはいえ、ややこしいので特別な事情が無い限りは基本元の名前を指定してあげよう。
なお、別名が日本語の場合、ORDER BYでの指定時はバッククォートというもので囲む必要がある。
このあたり、踏み込むとややこしいのでここでの解説は省略するが、列名として呼び出す場合はバッククォートが必要だ。
ちなみに、列の別名指定時は文字列を渡すことになるので、シングルクォートで大丈夫だ。
…実を言うと、私自身このバッククォート周りについては書きながら初めて知った。
別記事で備忘録としてまとめるので、公開したらここにリンクを貼ろう。
コメント