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
ます。したがって、 is が(つまり、前の行の) にcir
等しい限り、式は本質的に と同等ですが、とが異なる場合 (つまり、新しいグループに遭遇したことを意味します)、式は in factになります。つまり、列挙は今新たに始めました。@lastcir
cir
index
@index := @index + 1
cir
@lastcir
cir
@index := 0 + 1
必要に応じて、このソリューションを SQL Fiddle でテストできます。