MySQLでオートインクリメントを使用せずにグループ毎に連番を設定する方法
2025/06/19
MySQLでオートインクリメントを使用せずにグループ毎で連番を割り振りたかった。具体的には掲示板を作成する案件がありスレッド毎にレスナンバーを表示させたかった。以下にSQL文とPHPから実行させる方法をメモ。
目次
MySQL8系以降は別の方法が便利(2025/06/19追記)
MySQLのバージョンが8系以降の場合は以下の方法を用いる方が楽で便利。
SQL文
phpmyadminやadminerからは以下SQL文でgroup_idごとに連番(no)が割り振られる。
SET @no:=0;
SET @group_id:=null;
SELECT
*,
IF(@group_id <> group_id, @no:=1, @no:=@no+1) AS no,
@group_id := group_id
FROM test_table
ORDER BY group_id DESC;
PHPからSQL文を発行する場合は以下になる。
$sql = 'SET @no:=0;';
$row = $mysqli->query($sql);
$sql = 'SET @group_id:=null;';
$row = $mysqli->query($sql);
$sql = '
SELECT
*,
IF(@group_id <> group_id, @no:=1, @no:=@no+1) AS no,
@group_id := group_id
FROM test_table
ORDER BY group_id DESC
;
ページングにも対応させたい
掲示板だと数十件ほどの書き込みごとに「次のページへ」等のページングが必要になるが、先述のソースだとページが切り替わるごとに上からレスナンバーが1~とリセットされてしまう。
そのような場合は以下のように変更することでページが切り替わってもレスナンバーが正常に表示されるようになる。
$page = 1; //ページ数 $limit = 20; //1ページの最大表示数 $offset = $page * $limit; $sql = 'SET @no:=' . $offset . ';';
アットマークとかコロンとかは何?
今回作成したSQL文は参考サイトを元にしたが、アットマークとかコロンなど平素では使用しない記述が多数見受けられた。
@(アットマーク)
変数を利用する際に使用する。PHPでいう$マークみたいなものっぽい。
:=(コロン・イコール)
イコールと同じ、もしくは代入の際に使用する。例えば以下だとnoという変数に0を代入するという意味になる。
$sql = 'SET @no:=0;';
IF(@group_id <> group_id, @no:=1, @no:=@no+1) AS noの部分
IF~からASまでの部分は参考演算子とのこと。group_idが等しくない場合はnoは1、同じ場合は+1とする。つまり同じグループであればインクリメントしていくといったもの。その値をnoカラムとして受け取られる(AS no部分)。
参考サイト
関連記事
-
-
ON DUPLICATE KEY UPDATE後にinsert_idを取得すると結果が0になる
MySQLでON DUPLICATE KEY UPDATE句指定し、データの登録 ...
-
-
エックスサーバーでMySQLのサイズに注意
エックスサーバーで自動更新のログをMySQLに保存するようなシステムを動かしてい ...
-
-
SortableJSを使ってデータの並べ替え&保存
あるシステムを拝見した際にtableタグ内に並んでいる項目をドラッグ&ド ...
-
-
MySQLのview(ビュー)で仮想的なテーブルを作成する方法
MySQL関連のサイトを見ているとview(ビュー)が云々という記事を見かけた。 ...
-
-
MySQLで文字列を置換する方法
MySQLで文字列の置換を行いたかった。以下に方法をメモ。 目次1 ...