MySQL
 Computer >> コンピューター >  >> プログラミング >> MySQL

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 BYDESC に変更するだけで対応できます。

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句に書くサブクエリには、t1t2 のような別名を必ず付ける必要がある
  • 「最新のログを古い順に表示したい」「新着データを時系列で一覧化したい」といったケースに応用できる便利なテクニック
  1. 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 を組み合わせて最後

  2. 【MySQL】名前列の最後のスペースより左側の文字列をすべて抽出する方法

    名前データが格納された列から、フルネームのうち「最後のスペースより左側」の部分だけを取り出したい場面はよくあります。例えば、姓名が混在するデータから名(ファーストネーム)部分を抽出するようなケースです。MySQLでは LEFT()、LENGTH()、LOCATE()、REVERSE() の各関数を組み合わせることで、この処理を簡単に実現できます。 1. サンプルテーブルの作成 まず、名前を格納するテーブルを作成します。 mysql> create table DemoTable1939     (     F