首页 > 解决方案 > Mysql的排序顺序

问题描述

我有 1 个表,其中包含 id、name 和威胁列,并且希望对威胁列使用 order by 子句。

威胁 1 是最高优先级,而 5 是最低优先级。很少有记录没有威胁得分并且得分为 Null。

因此,在屏幕上显示它时,用数值 6 减去威胁分数(如果威胁有价值),相同的值将用作威胁分数。

在按 asc 排序列威胁时,它选择第一个空值(无威胁)并按 desc 排序,它选择第一个值为 5(最低威胁)。

因此,对于 ASC,屏幕上的最终订单是(减去 6 后)。如果您在此处看到,威胁评分为 5 显示为最高,因为 SQL 发送记录按威胁评分排序。

+-------------+------------+
| screen data | Table data |
+-------------+------------+
|    NULL     |     Null   |
|     1       |      5     |
|     2       |      4     |
|     3       |      3     |
|     4       |      2     |
|     0       |      0     |
+-------------+------------+

已经尝试过ORDER BY threat * -1 ASC,但它给出错误

BigInt 无符号错误超出范围

在这里,我的要求是在对记录进行排序时获得 1 作为最高记录的威胁评分,因为 NULL 有先例。

排序的预期行为(ASC 或 desc)

+--------+
| Threat | 
+--------+
|   1    |
|   2    |
|   3    |
|   4    |
|   5    |
|   0    |
|  NULL  |
+--------+

--工作解决方案--

在这里有很棒的人的帮助下,下面的解决方案就像魅力一样。

ORDER BY IF (threat=0,6, ifnull(threat,6)) ASC ; 

标签: mysqlsqlsql-order-by

解决方案


在这种情况下,您必须处理NULL值。NULL处理值的方法很少。您可以将默认值更改为适合您使用的某个数字,在这种情况下,NULL值将消失,您的问题将得到解决。另一种解决方案是有NULL值但在查询表时处理它们。您可以使用IFNULL(expression, alt_value),在您的情况下,它将是:

IFNULL(threat, 6)

如果架构是:

CREATE TABLE IF NOT EXISTS `threat_table` (
  `id` int(3) unsigned ,
  `name` varchar(200),
  `threat` int(3) unsigned
) DEFAULT CHARSET=utf8;

INSERT INTO `threat_table` (`id`, `name`, `threat`) VALUES
  ('1', 'test1', '5'),
  ('2', 'test2', NULL),
  ('3', 'test3', '4'),
  ('4', 'test4', '3'),
  ('5', 'test5', '2'),
  ('6', 'test6', '1');

你的查询是:

SELECT * from table order by IFNULL(threat, 6)

那么结果是令人满意的:

+----+-------+--------+
| id | name  | threat |
+----+-------+--------+
|  6 | test6 | 1      |
|  5 | test5 | 2      |
|  4 | test4 | 3      |
|  3 | test3 | 4      |
|  1 | test1 | 5      |
|  2 | test2 | (null) |
+----+-------+--------+

看看这个小提琴

更新:

如果威胁编号可以是 [1..5] 以外的任何值,我们可以使用以下查询:

select * from threat_table order by IFNULL(threat, ~0 >> 33)

推荐阅读