[MySQL]テーブルからの奇数行または偶数行を分けて取得する方法

[MySQL]テーブルからの奇数行または偶数行を分けて取得する方法
2023年10月01日2023年10月10日 PR

データを分割して取得したい時があります。そこでテーブルから奇数行と偶数行を分けて取得する方法を紹介します。

ちなみに奇数行と偶数行以外に3分割や5分割なども取得することも可能です。

前提条件

前提条件として、サロゲートキー(代理キー)を利用したオートインクリメントで連番のカラムが必要です。

safadfaaf

テーブル定義

CREATE TABLE `articles` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ;

奇数行または偶数行で分けて取得する

奇数行または偶数行で分けて取得する方法ですが、オートインクリメントで連番になっているカラム(今回だとid)を割り算して余り求めて取得行を制御します。

■偶数行の場合

SELECT 
    id, created_at
FROM
    articles
WHERE
    id % 2 = 0 -- 奇数、偶数なので2で割って余り0にする
;

偶数行の取得結果です。

23649234123

次に奇数行の取得方法は、余りの部分を「1」に書き換えて取得します。

■奇数行の場合

SELECT 
    id, created_at
FROM
    articles
WHERE
    id % 2 = 1 -- 奇数、偶数なので2で割って余り1にする
;

奇数行の取得結果です。

234123242

■MySQLのMOD関数でも可能

MOD関数は、剰余(割り算の余り)を行うためのMySQLの関数です。こちらを使用しても求めるができます。

参考:https://dev.mysql.com/doc/refman/8.0/ja/arithmetic-functions.html

奇数行、偶数行以外にも3分割、5分割とかもできる

割り算をおこなって余りを比較しているだけですので、奇数行、偶数行以外にも3分割、5分割など好きな数だけ分割することも可能です。

例えば、5分割したい場合は、余りの数を0~4を指定することで5分割で取得することができます。

// 5,10,15・・・が取得できる
SELECT id, created_at FROM articles WHERE id % 5 = 0;
// 1,6,11・・・が取得できる
SELECT id, created_at FROM articles WHERE id % 5 = 1;
// 2,7,12・・・が取得できる
SELECT id, created_at FROM articles WHERE id % 5 = 2;
// 3,8,13・・・が取得できる
SELECT id, created_at FROM articles WHERE id % 5 = 3;
// 4,9,14・・・が取得できる
SELECT id, created_at FROM articles WHERE id % 5 = 4;

インデックスが効かないけど早い

余りを求めて分割する方法は実行計画を確認するとALLとなっておりインデックスが効きません。

ですが、なぜか取得は早いです。

123123123

本番運用する場合は、ご自身の環境で実行計画がどのように扱われているかや取得時間など確認することをおすすめします。

まとめ

MySQLのテーブルから奇数行と偶数行を分けて取得する方法を紹介しました。

連番のカラムを使い、割り算と余りを利用して行を制御します、奇数行と偶数行の取得に加えて、3分割や5分割なども可能です。

この方法はインデックスが効かないですが高速に動作します。ぜひ試してみてください。

コメント

ID5
定年間近おやじ
昔は決済バッチの処理を分散するときによく使っていました。
最近はあまり見かけなくなりましたが、この方法は楽で良いですよね。
インデックスに触れられてますけど、100万レコードでも余裕で処理できますよ。
ID6
管理者太郎(管理人)
コメントありがとうございます。
処理を分散したい時に便利でした。
100万レコードでも余裕なんですね、今度試したいと思います。

コメントを残す

お名前(任意)
コメント:新規