Gordon Linoff 是对的:在 SQL 中,表确实没有内在的顺序。但是,仍然有一种方法可以在您的情况下分配索引。唯一的问题是,顺序是不确定的,并且 1 可能与 2 组合在一起,而 2 不一定是它后面的那个(以您可能期望的任何特定顺序)。也就是说,最终结果可能类似于您的示例:
num cir index
--- --- -----
1 1 1
2 2 1
3 3 1
4 1 2
5 2 2
6 3 2
7 1 3
8 2 3
9 3 3
但它很可能是这样的:
num cir index
--- --- -----
7 1 1
2 2 1
3 3 1
4 1 2
8 2 2
6 3 2
1 1 3
5 2 3
9 3 3
如果num正如您所说的那样,它不是“有序的”(因此,我假设它不能用于排序)。
cir这个想法是仅对列上的数据集进行排序
num cir
--- ---
1 1
4 1
7 1
2 2
5 2
8 2
3 3
6 3
9 3
然后使用变量赋值来生成index值
num cir index
--- --- -----
1 1 1 1
4 1 2 2
7 1 3 3
2 2 1 -> 1
5 2 2 2
8 2 3 3
3 3 1 1
6 3 2 2
9 3 3 3
就是这样:
SELECT
num,
cir,
`index`
FROM (
SELECT
num,
@index := @index * (cir = @lastcir) + 1 AS `index`,
@lastcir := cir AS cir
FROM
yourtable,
(SELECT @index := 0, @lastcir := 0) v
ORDER BY
cir
) s
ORDER BY
`index`,
cir
;
可以猜到,这个表达式
@index := @index * (cir = @lastcir) + 1
是分配索引的那个。基本上,如果你删除* (cir = @lastcir)部分,你会得到
@index := @index + 1
这可能不需要解释:它只是增加@index值。
每次cir遇到新值时,该附加位都会重置枚举(请记住,数据集按 排序cir)。在 MySQL 中,布尔表达式,如cir = @lastcir,在需要数字的上下文中隐式转换为数字,例如算术表达式的上下文。更具体地说,它被转换为1fortrue和0for false。因此,只要cir等于@lastcir(即前一行的)cir,表达式本质index上等于现在重新开始。@index := @index + 1cir@lastcircir@index := 0 + 1
如果您愿意,可以在 SQL Fiddle测试此解决方案。