MySQLでUNIONを使って前後のレコードを1つのクエリで取得する方法
MySQLでは、UNIONを活用することで、指定したレコードの「前」と「次」のレコードを1つのクエリで同時に取得できます。この記事では、基本構文から実際に動くサンプルまで、手順を追ってわかりやすく解説します。
基本となる構文
前後のレコードを取得するための基本的な構文は以下の通りです。
(select * from テーブル名 WHERE IDカラム名 > 基準値 ORDER BY IDカラム名 ASC LIMIT 1) UNION (select * from テーブル名 WHERE IDカラム名 < 基準値 ORDER BY IDカラム名 DESC LIMIT 1);
ポイントは、「次のレコード」を取得する場合は昇順(ASC)で並べ替えて先頭の1件を、「前のレコード」を取得する場合は降順(DESC)で並べ替えて先頭の1件を取得する点です。この2つのSELECT結果をUNIONで結合することで、目的のデータが一度に得られます。
サンプルテーブルの作成
それでは、実際の動きを確認するためにテーブルを作成しましょう。以下のクエリを実行します。
mysql> create table previousAndNextRecordDemo
-> (
-> Id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> Name varchar(30)
-> );
Query OK, 0 rows affected (1.04 sec)
自動採番される「Id」カラムと、名前を格納する「Name」カラムだけを持つシンプルなテーブルです。
テストデータの挿入
続いて、INSERT文で複数のレコードを挿入していきます。
mysql> insert into previousAndNextRecordDemo(Name) values('John');
Query OK, 1 row affected (0.17 sec)
mysql> insert into previousAndNextRecordDemo(Name) values('Sam');
Query OK, 1 row affected (0.15 sec)
mysql> insert into previousAndNextRecordDemo(Name) values('Carol');
Query OK, 1 row affected (0.14 sec)
mysql> insert into previousAndNextRecordDemo(Name) values('Bob');
Query OK, 1 row affected (0.17 sec)
mysql> insert into previousAndNextRecordDemo(Name) values('Larry');
Query OK, 1 row affected (0.20 sec)
mysql> insert into previousAndNextRecordDemo(Name) values('David');
Query OK, 1 row affected (0.14 sec)
mysql> insert into previousAndNextRecordDemo(Name) values('Ramit');
Query OK, 1 row affected (0.12 sec)
mysql> insert into previousAndNextRecordDemo(Name) values('Maxwell');
Query OK, 1 row affected (0.15 sec)
mysql> insert into previousAndNextRecordDemo(Name) values('Mike');
Query OK, 1 row affected (0.14 sec)
mysql> insert into previousAndNextRecordDemo(Name) values('Robert');
Query OK, 1 row affected (0.19 sec)
mysql> insert into previousAndNextRecordDemo(Name) values('Chris');
Query OK, 1 row affected (0.10 sec)
mysql> insert into previousAndNextRecordDemo(Name) values('James');
Query OK, 1 row affected (0.16 sec)
mysql> insert into previousAndNextRecordDemo(Name) values('Jace');
Query OK, 1 row affected (0.15 sec)
登録されたデータの確認
SELECT文ですべてのレコードを表示してみましょう。
mysql> select *from previousAndNextRecordDemo;
実行結果は以下の通りです。全部で13件のレコードが登録されています。
+----+---------+ | Id | Name | +----+---------+ | 1 | John | | 2 | Sam | | 3 | Carol | | 4 | Bob | | 5 | Larry | | 6 | David | | 7 | Ramit | | 8 | Maxwell | | 9 | Mike | | 10 | Robert | | 11 | Chris | | 12 | James | | 13 | Jace | +----+---------+ 13 rows in set (0.00 sec)
UNIONで前後のレコードを取得する
それでは、Id=8(Maxwell)を基準として、その前後のレコードを1つのクエリで取得してみましょう。
mysql> (select *from previousAndNextRecordDemo WHERE Id > 8 ORDER BY Id ASC LIMIT 1)
-> UNION
-> (select *from previousAndNextRecordDemo WHERE Id < 8 ORDER BY Id DESC LIMIT 1);
実行結果:
+----+-------+ | Id | Name | +----+-------+ | 9 | Mike | | 7 | Ramit | +----+-------+ 2 rows in set (0.03 sec)
結果を見ると、基準となるId=8に対して、次のレコードであるId=9の「Mike」と、前のレコードであるId=7の「Ramit」が正しく取得できていることがわかります。
まとめ
UNIONを使えば、前後のレコードを別々にクエリを実行する必要がなく、1回の実行で両方をまとめて取得できます。ブログやCMSにおける「前の記事・次の記事」ナビゲーションの実装など、実務でもよく使われるテクニックなので、ぜひマスターしておきましょう。
-
MySQLで重複するタプルを検出してカウントを表示する方法
MySQLで重複するタプル(同じ値の組み合わせを持つ行)を検出し、その出現回数を表示するには、GROUP BY句とHAVING句を組み合わせて使用します。この記事では、テーブルの作成から重複検出クエリの実行まで、手順を追って解説します。 サンプルテーブルの作成 まず、デモ用のテーブルを作成します。 mysql> create table DemoTable -> ( -> Id int, -> Name varchar(20) -> ); Query OK, 0 rows affected (0.80 sec) テストデータの挿入
-
MySQLでAND・OR演算子を組み合わせた単一クエリを使って特定のレコードを取得する方法
MySQLでは、AND演算子とOR演算子をWHERE句で組み合わせることで、複数の条件を指定しながら特定のレコードを1つのクエリで取得できます。本記事では、実際にテーブルを作成し、データを挿入して、AND・ORを組み合わせたクエリの動作を確認していきます。 1. テーブルの作成 まず、CREATE TABLE文でサンプル用のテーブルを作成します。 mysql> create table DemoTable2015 -> ( -> StudentId int, -> StudentName varchar(20), -> Stude