我有以下初始情况:
+------------+-------------+
| 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
目标是将每一行没有空值的
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 行未占用的位置排序时,但永远不会移动强制行。
按此顺序,我尝试在
CASE WHEN
中使用 ORDER BY
语法,如下所示:
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
那样比较
SELECT * FROM two_column_order
order by
CASE when `forcedRank` IS NOT NULL THEN `forcedRank`
ELSE `legacyRank`
END
legacyRank | 强制等级 |
---|---|
0 | 空 |
1 | 空 |
4 | 1 |
6 | 2 |
3 | 空 |
5 | 空 |
2 | 6 |
7 | 空 |
因为第一个答案不会给你正确答案。
我改变了顺序,在原来的数字上加了一个小数点,这样它就会比新的强制排名大。
它会保持顺序并且强制数字小于legayrank,它会让你得到以下结果
SELECT * FROM two_column_order
order by
CASE when `forcedRank` IS NOT NULL THEN `forcedRank`
ELSE `legacyRank` + .1
END
legacyRank | 强制等级 |
---|---|
0 | 空 |
4 | 1 |
1 | 空 |
6 | 2 |
3 | 空 |
5 | 空 |
2 | 6 |
7 | 空 |