MySQLで最後の20レコードを昇順に取得する方法|サブクエリとLIMIT句の使い方
MySQLでテーブルの末尾(最後)の20件を昇順で取得したい場面はよくあります。しかし、単純に ORDER BY ... ASC LIMIT 20 と書くだけでは「先頭の20件」が返されてしまい、意図した結果になりません。
この問題を解決するのが、サブクエリとLIMIT句を組み合わせた2段階の手法です。考え方はシンプルです。
- 内側のサブクエリで、対象カラムを降順(DESC)に並べ替え、
LIMIT 20で末尾20件を取り出す - 外側のクエリで、その結果を昇順(ASC)に並べ替え直す
基本構文
SELECT * FROM
(
SELECT * FROM yourTableName ORDER BY yourColumnName DESC LIMIT 20
) anyVariableName
ORDER BY anyVariableName.yourColumnName;
サンプルテーブルの作成
実際の動きを確認するため、「ProductInformation」というテーブルを作成します。
mysql> create table ProductInformation
-> (
-> ProductId int,
-> ProductName varchar(100),
-> ProductPrice int
-> );
Query OK, 0 rows affected (0.50 sec)
テストデータの投入
続いてINSERT文でレコードを登録します。ここでは ProductId 101〜123 の合計23件を挿入しています。
mysql> insert into ProductInformation values(101,'Product-1',200); Query OK, 1 row affected (0.16 sec) mysql> insert into ProductInformation values(102,'Product-2',300); Query OK, 1 row affected (0.23 sec) -- 中略(ProductId 103〜122まで同様に挿入) -- mysql> insert into ProductInformation values(123,'Product-23',10000); Query OK, 1 row affected (0.15 sec)
登録データの確認
SELECT文ですべてのレコードを表示してみましょう。
mysql> select *from ProductInformation;
実行結果は以下の通りです。23件のデータが登録されていることがわかります。
+-----------+-------------+--------------+ | ProductId | ProductName | ProductPrice | +-----------+-------------+--------------+ | 101 | Product-1 | 200 | | 102 | Product-2 | 300 | | 103 | Product-3 | 700 | | 104 | Product-4 | 100 | | 105 | Product-5 | 1500 | | 106 | Product-6 | 1200 | | 107 | Product-7 | 1300 | | 108 | Product-8 | 1600 | | 109 | Product-9 | 1250 | | 110 | Product-10 | 1900 | | 111 | Product-11 | 1870 | | 112 | Product-12 | 1876 | | 113 | Product-13 | 1869 | | 114 | Product-14 | 1456 | | 115 | Product-15 | 1860 | | 116 | Product-16 | 359 | | 117 | Product-17 | 1667 | | 118 | Product-18 | 1467 | | 119 | Product-19 | 2134 | | 120 | Product-20 | 3450 | | 121 | Product-21 | 198 | | 122 | Product-22 | 195 | | 123 | Product-23 | 10000 | +-----------+-------------+--------------+ 23 rows in set (0.00 sec)
最後の20件を昇順で取得するクエリ
それでは本題のクエリです。サブクエリで ProductId の降順に並べて末尾20件を取り出し、外側で昇順に並べ替えています。
mysql> select *from
-> (
-> select *from ProductInformation order by ProductId desc limit 20
-> ) t1 order by t1.ProductId asc;
実行結果:
+-----------+-------------+--------------+ | ProductId | ProductName | ProductPrice | +-----------+-------------+--------------+ | 104 | Product-4 | 100 | | 105 | Product-5 | 1500 | | 106 | Product-6 | 1200 | | 107 | Product-7 | 1300 | | 108 | Product-8 | 1600 | | 109 | Product-9 | 1250 | | 110 | Product-10 | 1900 | | 111 | Product-11 | 1870 | | 112 | Product-12 | 1876 | | 113 | Product-13 | 1869 | | 114 | Product-14 | 1456 | | 115 | Product-15 | 1860 | | 116 | Product-16 | 359 | | 117 | Product-17 | 1667 | | 118 | Product-18 | 1467 | | 119 | Product-19 | 2134 | | 120 | Product-20 | 3450 | | 121 | Product-21 | 198 | | 122 | Product-22 | 195 | | 123 | Product-23 | 10000 | +-----------+-------------+--------------+ 20 rows in set (0.00 sec)
このように、ProductId 104〜123 の末尾20件が昇順(IDの小さい順)に整然と並んで取得できました。
補足:降順で取得したい場合
逆に、新しいレコードから順に表示したい(降順)場合は、外側の ORDER BY を DESC に変更するだけで対応できます。
mysql> select *from -> ( -> select *from ProductInformation order by ProductId desc limit 20 -> ) t2 order by t2.ProductId desc;
実行結果:
+-----------+-------------+--------------+ | ProductId | ProductName | ProductPrice | +-----------+-------------+--------------+ | 123 | Product-23 | 10000 | | 122 | Product-22 | 195 | | 121 | Product-21 | 198 | | 120 | Product-20 | 3450 | | 119 | Product-19 | 2134 | | 118 | Product-18 | 1467 | | 117 | Product-17 | 1667 | | 116 | Product-16 | 359 | | 115 | Product-15 | 1860 | | 114 | Product-14 | 1456 | | 113 | Product-13 | 1869 | | 112 | Product-12 | 1876 | | 111 | Product-11 | 1870 | | 110 | Product-10 | 1900 | | 109 | Product-9 | 1250 | | 108 | Product-8 | 1600 | | 107 | Product-7 | 1300 | | 106 | Product-6 | 1200 | | 105 | Product-5 | 1500 | | 104 | Product-4 | 100 | +-----------+-------------+--------------+ 20 rows in set (0.00 sec)
まとめ
- MySQLで末尾のN件を昇順に取得するには、「降順+LIMIT」のサブクエリを作り、外側のクエリで昇順に並べ替える
- FROM句に書くサブクエリには、
t1やt2のような別名を必ず付ける必要がある - 「最新のログを古い順に表示したい」「新着データを時系列で一覧化したい」といったケースに応用できる便利なテクニック
-
MySQLでテーブルの最後の3行を昇順に取得する方法
MySQLでテーブルの最後の数行を昇順(ASC)で取得したい場合、単純に ORDER BY 昇順+LIMIT を使うと「先頭」の行が取れてしまいます。そこで、サブクエリを使って一度降順(DESC)で末尾の行を取得し、その結果を外側で昇順に並べ替えるのが定番のテクニックです。基本構文select * from (select * from yourTableName order by yourColumnName desc limit 3) anyAliasName order by yourColumnName;この構文では、内側のサブクエリで DESC と LIMIT 3 を組み合わせて最後
-
【MySQL】名前列の最後のスペースより左側の文字列をすべて抽出する方法
名前データが格納された列から、フルネームのうち「最後のスペースより左側」の部分だけを取り出したい場面はよくあります。例えば、姓名が混在するデータから名(ファーストネーム)部分を抽出するようなケースです。MySQLでは LEFT()、LENGTH()、LOCATE()、REVERSE() の各関数を組み合わせることで、この処理を簡単に実現できます。 1. サンプルテーブルの作成 まず、名前を格納するテーブルを作成します。 mysql> create table DemoTable1939 ( F