我的初始情况如下:
+------------+-------------+ | 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
小提琴
因为第一个答案不会给你正确的答案。
我通过在原始数字上添加小数点来更改顺序,以便它比新的强制排名更大。
它将保持顺序,并且强制数字小于传统排名,它会得到以下结果
小提琴