MySQLやSQLiteなど、LIMIT句、OFFSET句が使用できる環境なら「取得したデータの何番目のデータを取得する」というのは簡単に出来るが、AccessなどLIMIT句などが使えない環境で同様のことをするにはどうすればいいか?
やり方のひとつとして、以下にメモしておく。
データ
サンプルデータは以下の通り。
ID(主キー) | DATA |
---|---|
1 | ABC |
2 | DEF |
3 | GHI |
4 | JKL |
5 | MNO |
クエリ(SQL文)
取得したデータのうち、3番目から2レコードだけ抽出する場合
LIMIT、OFFSET句を使った場合
SELECT * FROM table01 LIMIT 2 OFFSET 2;
ID | DATA |
---|---|
3 | GHI |
4 | JKL |
すごいシンプル、分かりやすい。
LIMIT、OFFSET句を使わない場合
で、Accessで上記をやろうとした場合のSQL文例。
SELECT TOP 2 * FROM table01
LEFT JOIN (SELECT TOP 2 * FROM table01) AS t2
ON table01.ID = t2.ID
WHERE t2.ID IS NULL;
table01.ID | table01.DATA | t2.ID | t2.DATA |
---|---|---|---|
3 | GHI | NULL | NULL |
4 | JKL | NULL | NULL |
逆にMySQLでTOP句は使えないんだけどね。
解説
代わりに使っているのがTOP句と外部結合(LEFT JOIN 〜 ON 〜)。
TOPは、上から指定個数のデータを取得する。
LEFT JOINは、2つのテーブルを指定条件で結合する。
ステップ毎にデータの動きを見ると分かりやすい。
(SELECT TOP 2 * FROM table01) AS t2
まず、この部分。
これはtable01テーブルの上位2レコードを抽出し、t2テーブルとして定義している。
ID | DATA |
---|---|
1 | ABC |
2 | DEF |
こんな感じ。
で、次にtable01とt2の外部結合を見てみる。
(t2テーブルの部分は省略して記載する)
table01 LEFT JOIN t2 ON table01.ID = t2.ID
table01.ID | table01.DATA | t2.ID | t2.DATA |
---|---|---|---|
1 | ABC | 1 | ABC |
2 | DEF | 2 | DEF |
3 | GHI | NULL | NULL |
4 | JKL | NULL | NULL |
5 | MNO | NULL | NULL |
LEFT JOINは、左辺のテーブルを全て列挙した上で、右辺のテーブルと結合する。
よって、結合できていない部分にはNULLが入る。
ここまで来れば、あとは単純なSELECTで任意の個数を取得するだけ。
(同様に省略形式で記載する)
SELECT TOP 2 * FROM 結合結果 WHERE t2.ID IS NULL;
これで、下記の結果となる。
table01.ID | table01.DATA | t2.ID | t2.DATA |
---|---|---|---|
3 | GHI | NULL | NULL |
4 | JKL | NULL | NULL |
以上