搜索

首页  >  问答  >  正文

按两列对 mysql 结果进行排序,但有一个“空洞”列

我的初始情况如下:

  +------------+-------------+
  | 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行而不移动它们?

P粉118698740P粉118698740499 天前444

全部回复(1)我来回复

  • P粉141925181

    P粉1419251812023-09-12 09:02:45

    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

    小提琴

    因为第一个答案不会给你正确的答案。

    我通过在原始数字上添加小数点来更改顺序,以便它比新的强制排名更大。

    它将保持顺序,并且强制数字小于传统排名,它会得到以下结果

    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

    小提琴

    回复
    0
  • 取消回复