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
,在需要数字的上下文中隐式转换为数字,例如算术表达式的上下文。更具体地说,它被转换为1
fortrue
和0
for false
。因此,只要cir
等于@lastcir
(即前一行的)cir
,表达式本质index
上等于现在重新开始。@index := @index + 1
cir
@lastcir
cir
@index := 0 + 1
如果您愿意,可以在 SQL Fiddle测试此解决方案。