第17回 その他のちょっとしたテクニック - MySQL講座
サカイ先生のMySQL講座
Lecutures on PHP
第17回 その他のちょっとしたテクニック (その1)
はじめに
みなさんこんにちは、サカイです。第1シーズンからあわせて17回にわたってお届けしてきたMySQL講座も、今回が最終回となりました。今回はこれまでの講座で説明しきれなかったテクニックについてアラカルトでお伝えしたいと思います。
今回は・・・
- 先輩にこうやって教えてもらえるのも今日が最後なんですね。。なんだか寂しいなぁ。
- なんだい、ノッケからテンションの低いこと言って。さぁ、時間が勿体ないから、はじめるよ。
- なんだか最近の先輩って今まで以上にテキパキしていますね(笑)。
- 「今まで以上に」というところに太郎君の気配りを感じるね。
- だって「最近はテキパキしていますね」なんて言った日には、なんて言い返されるやら・・・(笑)
- さて。実は前回までで MySQL操作の基本として押さえておいて欲しいことは全部説明し終わっているんだ。今日はそんな話から漏れてしまったちょっとしたお話しをしようかと思っている。あるいは太郎君がちょっと聞いてみたいと思うことがあれば、説明するよ。
- ア・ラ・カルトですね。
- おしゃれなこと、言うね(笑)。我々の勉強もそうやってシャレて行きたいもんだね。では、Allons!
1. Webサイトなどでよくある「ページ制御」
- 早速ですけど、ずっと疑問に思っていたことがあるんです。よくWebサイトでやっている「次ページへ」とかで 10件ずつ表示してるのがありますよね。あれは SQLで制御しているんですか?
- いい質問だね。太郎君は SQLを勉強する前にもたぶん関係するPHPのプログラムを改修したりしていたと思うけど、見覚え、ないかな?
- 恥ずかしながら全然記憶にないのです。たぶん暗号の連続にしか見えていなかったのだと思います。
- じゃぁ説明しようか。例えば全部で数千件も数万件もあるデータを一気にページ内で見せることはできないから、普通は10件とか50件とかで区切って「次ページへ」「3ページ目を表示中(135ページ中)」などの表示をするよね。
いろいろなやり方があるのだけど LIMIT 句を使う方法がぼくがやってきた中ではもっとも多く使われてきたね。
- SELECT ~ LIMIT 5; とかやるやつですね。覚えています!
- そう。最近はLIMIT の後ろに数字をひとつだけ指定する使い方が多かったと思うけど、ここには2つの数字を指定できるんだよね。
LIMIT [開始位置, ] 表示件数
というのが LIMIT句の構文だ。 ちなみに開始位置の一番最初はゼロ番目になるから注意してね。ちょっと練習してみるかい?
- はい、やってみたいです。何がいいですかね・・・・
- そうだな。商品テーブル(items)の全件を表示する想定にしてみようか。いっぺんにいっぱい表示されても確認が大変なので、ここでは1ページ5件ずつということにしよう。
- わかりました。やってみます。まず1ページ目を表示するためには、0番目から5件を表示という指定すればいいのだから・・・
mysql> SELECT * FROM items ORDER BY id LIMIT 0,5;
+----+------------+------------+
| id | name | base_price |
+----+------------+------------+
| 1 | スーパー01 | 8520 |
| 2 | スーパー07 | 5950 |
| 3 | スーパー15 | 2210 |
| 4 | スーパー18 | 3590 |
| 5 | スーパー22 | 7360 |
+----+------------+------------+
5 rows in set (0.00 sec)
- お! 何も言わなくてもちゃんと ORDER BY をつけているね。感心感心。
- PHPプロ!の連載(第4回参照)で「ORDER BY をつけないと順不同」って書いてあったので、違うページをとるたびに違う並び順で出てきたら意味ないなぁとおもったんです。
- そうだね。RDBMSを Excel の「表(ひょう)」のようにイメージして理解しがちだけど、本当は表のように順序(何行目、とか)があるわけじゃなくて、あくまでも集合として各レコードが "がさっ" と袋に入っているようなイメージなんだ。
だから順序を意識したい時には ORDER BY をつけて並べさせるというわけだね。今はまだ「集合」の話になると難しいかもしれないけど、データベースを仕事で使っていくならそう遠くない時期にはこういう理論の本も読んでほしいな。
- はい。そんな話題でも早く先輩と会話が成立するようになりたいです! でもまず今は、「順不同」を意識していたので合格点というわけですね(^^)。
- そうだね(笑)。 話を戻して、じゃぁ次は「2ページ目」の表示と「31ページ目」の表示をやってごらん。
- はい。1ページ目では 0 番目から5件、つまり 0,1,2,3,4 番目を表示したのだから2ページ目は 5 番目から5件という指定をすればいいですね。 LIMIT 5,5。 リミット・ゴーゴー!なんちゃって。
mysql> SELECT * FROM items ORDER BY id LIMIT 5,5;
+----+------------+------------+
| id | name | base_price |
+----+------------+------------+
| 6 | スーパー30 | 11980 |
| 7 | スーパー32 | 8810 |
| 8 | スーパー39 | 690 |
| 9 | スーパー49 | 2340 |
| 10 | スーパー53 | 3430 |
+----+------------+------------+
5 rows in set (0.00 sec)
- 同様に考えると31ページ目は、、、 5,6,7,.... 数えてられないや。1ページ目が0から、2ページ目が5からだから、 (ページ番号-1)*5 という式で表せそうです。とすると 31ページ目は (31-1)*5 = 30*5 = 150番目! ということで LIMIT 150,5 でよさそうです。
mysql> SELECT * FROM items ORDER BY id LIMIT 150,5;
+-----+--------------+------------+
| id | name | base_price |
+-----+--------------+------------+
| 151 | エクストラ98 | 3110 |
| 152 | 超01 | 10340 |
| 153 | 超03 | 7440 |
| 154 | 超06 | 6260 |
| 155 | 超08 | 3980 |
+-----+--------------+------------+
5 rows in set (0.00 sec)
- すばらしいね。完璧だよ。
まずは配列や文字列の扱いから、じっくり勉強して行きましょう。