我已经解决了,感谢这里最优秀的博客文章的帮助:http ://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/
该解决方案非常重要,需要变量和一些有关 mysql 如何对其查询操作进行排序的高级知识,但它似乎具有相当高的性能。关键之一是变量赋值可以隐藏在函数调用中!
本质上,以下查询解决了这个问题:
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 |
+------+----------+-----------+
耶!