ここの最も優れたブログ投稿の助けのおかげで、私はそれを解決しました: http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/
解決策は簡単ではなく、変数と、mysql がクエリ操作をどのように順序付けるかについての高度な知識が必要ですが、かなりパフォーマンスが高いようです。重要な点の 1 つは、変数の割り当てを関数呼び出し内に隠すことができることです。
基本的に、次のクエリは問題を解決します。
SET @num := 0, @type := '';
SELECT name, subgroup, @num AS increment
FROM table_name
WHERE 0 <= GREATEST(
@num := IF(@type = subgroup, @num + 1, 1),
LEAST(0, LENGTH(@type := subgroup)))
関数GREATEST
、LEAST
、およびLENGTH
は、変数割り当てのコンテナーとして存在します。ご覧のとおり、これらの関数は基本的に、クエリの出力に影響を与えることは何もしていません。
ただし、テーブルに連続していない「サブグループ」値があることもわかりました。例えば:
+------+----------+
| name | subgroup |
+------+----------+
| john | 1 |
| doe | 1 |
| jim | 1 |
| greg | 2 |
| boe | 2 |
| amos | 3 |
| ben | 1 |
| gary | 2 |
+------+----------+
次のような出力テーブルが得られました。
+------+----------+-----------+
| name | subgroup | increment |
+------+----------+-----------+
| john | 1 | 1 |
| doe | 1 | 2 |
| jim | 1 | 3 |
| greg | 2 | 1 |
| boe | 2 | 2 |
| amos | 3 | 1 |
| ben | 1 | 1 |
| gary | 2 | 1 |
+------+----------+-----------+
実行順序が原因で、クエリの最後に句を追加してORDER BY
も機能しませんでした。また、ORDER BY
句内の変数の割り当てを非表示にすることはより近づきましたが、独自の問題があったため、使用した最終的なクエリは次のとおりです。
SET @num := 0, @type := '';
SELECT name, subgroup, @num AS increment
FROM (SELECT * FROM table_name ORDER BY subgroup) AS table_name2
WHERE 0 <= GREATEST(
@num := IF(@type = subgroup, @num + 1, 1),
LEAST(0, LENGTH(@type := subgroup)))
次の出力が得られます。
+------+----------+-----------+
| name | subgroup | increment |
+------+----------+-----------+
| john | 1 | 1 |
| doe | 1 | 2 |
| jim | 1 | 3 |
| ben | 1 | 4 |
| greg | 2 | 1 |
| boe | 2 | 2 |
| gary | 2 | 3 |
| amos | 3 | 1 |
+------+----------+-----------+
わーい!