我的初始情況如下:
+------------+-------------+ | legacyRank | forcedRank | +------------+-------------+ | 0 | NULL | | 1 | 6 | | 2 | NULL | | 3 | 1 | | 4 | NULL | | 5 | NULL | | 6 | 2 | +------------+-------------+
您可以透過以下架構產生此表:
CREATE TABLE two_column_order ( legacyRank VARCHAR(45), forcedRank VARCHAR(45) ); INSERT INTO two_column_order (legacyRank, forcedRank) VALUES (5, NULL); INSERT INTO two_column_order (legacyRank, forcedRank) VALUES (6, 2); INSERT INTO two_column_order (legacyRank, forcedRank) VALUES (7, NULL); INSERT INTO two_column_order (legacyRank, forcedRank) VALUES (0, NULL); INSERT INTO two_column_order (legacyRank, forcedRank) VALUES (1, NULL); INSERT INTO two_column_order (legacyRank, forcedRank) VALUES (2, 6); INSERT INTO two_column_order (legacyRank, forcedRank) VALUES (3, NULL); INSERT INTO two_column_order (legacyRank, forcedRank) VALUES (4, 1); SELECT * FROM two_column_order order by CASE when `forcedRank` <> NULL THEN `forcedRank` ELSE `legacyRank` END
目標是將每行不包含 NULL forcedRank
列的行放置在此 forcedRank
列中提到的準確位置。預期的渲染如下:
+------------+-------------+ | legacyRank | forcedRank | +------------+-------------+ 0 | 0 | NULL | 1 | 3 | 1 | 2 | 6 | 2 | 3 | 2 | NULL | 4 | 4 | NULL | 5 | 5 | NULL | 6 | 6 | 6 | +------------+-------------+
如您所見,如果不是 NULL,則每行都會採用按 forcedRank
列排序的位置。當 NULL 行仍然按 legacyRank
列在未被非 NULL 行佔據的位置排序時,但絕不移動強制行。
依照這個順序,我嘗試在 ORDER BY
中使用 CASE WHEN
語法,如下所示:
SELECT * FROM two_column_order order by CASE WHEN (`forcedRank` is NULL ) THEN `legacyRank` END , -`forcedRank` DESC, `legacyRank`
但是結果並沒有真正達到我的期望:
+------------+-------------+ | legacyRank | forcedRank | +------------+-------------+ | 3 | 1 | | 6 | 2 | | 6 | 6 | | 0 | NULL | | 2 | NULL | | 4 | NULL | | 5 | NULL | +------------+-------------+
那麼如何讓 legacyRank
列的順序超出forcedrank行而不移動它們?
NULL
不能像您需要使用IS
那樣進行比較,或者在您的情況下使用IS NOT
小提琴
因為第一個答案不會給你正確的答案。
我透過在原始數字上添加小數點來更改順序,以便它比新的強制排名更大。
它將保持順序,並且強制數字小於傳統排名,它會得到以下結果
小提琴