我有 1 个表,其中包含 id、name 和 threat 列,并且想对 threat 列使用 order by 子句。
威胁 1 是最高优先级,5 是最低优先级。很少有记录没有威胁分数,并且分数为 Null。
因此在屏幕上显示它时,用数值 6 减去威胁分数(如果威胁有值(value)),相同的值将用作威胁分数。
在按 asc 对列威胁进行排序时,它选择第一个空值(无威胁)并按 desc 排序,它选择第一个值为 5(最低威胁)。
因此屏幕上的最终顺序是(减去 6 后)ASC。如果您在此处看到,威胁评分 5 显示为最高,因为 SQL 发送记录按威胁评分排序。
+-------------+------------+
| screen data | Table data |
+-------------+------------+
| NULL | Null |
| 1 | 5 |
| 2 | 4 |
| 3 | 3 |
| 4 | 2 |
| 0 | 0 |
+-------------+------------+
已经尝试过 ORDER BY threat * -1 ASC
但它给出错误
BigInt unsigned error out of range
这里我的要求是在对记录进行排序时获得威胁得分为 1 的最高记录,因为 NULL 有先例。
排序的预期行为(ASC 或 desc)
+--------+
| Threat |
+--------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 0 |
| NULL |
+--------+
--工作解决方案--
在这里很棒的人的帮助下,下面的解决方案非常有效。
ORDER BY IF (threat=0,6, ifnull(threat,6)) ASC ;
最佳答案
在这种情况下,您必须处理 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) |
+----+-------+--------+
看看this fiddle .
更新:
如果威胁数可以是 [1..5] 以外的任何值,我们可以使用此查询:
select * from threat_table order by IFNULL(threat, ~0 >> 33)
关于Mysql排序顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56536792/