MySqlを使用して、行を最低から最高に継続的に、または繰り返しソートしようとしています。たとえば、列の値が 1,3,2,4,2,1,4,3,5 の場合、最終的には 1,2,3,4,5,1,2 のようになります。 3,4. したがって、最低から最高に移動しますが、最低から最高に何度も並べ替えを試みます。
3 に答える
大規模なセットの場合、semi-JOIN操作(Strawberryからの回答のアプローチ)により、扱いにくい結果セットが作成される場合があります。(ここでも、MySQLにはいくつかの最適化が含まれている可能性があります。)
MySQLで利用可能な別の代替手段は、次のような「ユーザー変数」を使用することです。
SELECT r.mycol
FROM ( SELECT IF(q.mycol=@prev,@seq := @seq + 1,@seq := 1) AS seq
, @prev := q.mycol AS mycol
FROM mytable q
JOIN (SELECT @prev := NULL, @seq := NULL) p
ORDER BY q.mycol
) r
ORDER BY r.seq, r.mycol
それを少し解凍して、内部クエリ(インラインビューのエイリアスとして。)から始めて、それが何をしているのかを説明しましょう。並べ替えたい値を含むr
列()を取得するようにMySQLに指示しています(例:1,3,2)。 mycol
、4,2,1,4,3,5であり、MySQLにこれらを昇順で並べ替えるように指示しています:1,1,2,2,3,3,4,4,5。
ここでの「トリック」は、MySQLユーザー変数を使用してmycol
、現在の行のmycol
値を前の行の値と比較し、それを使用して、それぞれに1..nから昇順のシーケンス値を割り当てることです。明確な値。
その結果セットを使用して、最初に割り当てられたシーケンス値で並べ替え、次にからの値で並べ替えるようにMySQLに指示できますmycol
。
各行に一意のIDがある場合は、相関サブクエリを使用して同等の結果を得ることができます(ただし、このアプローチが大規模なセットでも同様に実行される可能性はほとんどありません)。
SELECT r.mycol
FROM mytable r
ORDER
BY ( SELECT COUNT(1)
FROM mytable q
WHERE q.mycol = r.mycol
AND q.id <= r.id
)
, r.mycol
テストケースの設定は次のとおりです。
CREATE TABLE mytable (id INT, mycol INT);
INSERT INTO mytable (id, mycol) VALUES
(1,1),(2,3),(3,2),(4,4),(5,2),(6,1),(7,4),(8,3),(9,5);
これだけで2回注文はありません
ORDER BY column ASC
PK が一意の整数であるとしましょう。次のことを検討してください...
CREATE TABLE seq(id INT NOT NULL PRIMARY KEY,val INT);
INSERT INTO seq VALUES (8,1),(4,2),(1,3),(2,4),(7,0),(6,1),(3,2),(5,5);
SELECT * FROM seq ORDER BY val;
+----+------+
| id | val |
+----+------+
| 7 | 0 |
| 6 | 1 |
| 8 | 1 |
| 3 | 2 |
| 4 | 2 |
| 1 | 3 |
| 2 | 4 |
| 5 | 5 |
+----+------+
SELECT x.*
, COUNT(*) rank
FROM seq x
JOIN seq y
ON y.val = x.val
AND y.id <= x.id
GROUP
BY id
ORDER
BY rank
, val;
+----+------+------+
| id | val | rank |
+----+------+------+
| 7 | 0 | 1 |
| 6 | 1 | 1 |
| 3 | 2 | 1 |
| 1 | 3 | 1 |
| 2 | 4 | 1 |
| 5 | 5 | 1 |
| 8 | 1 | 2 |
| 4 | 2 | 2 |
+----+------+------+