Mysql的排序顺序

Posted

技术标签:

【中文标题】Mysql的排序顺序【英文标题】:Mysql order of sorting 【发布时间】:2019-06-11 05:03:35 【问题描述】:

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

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

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

在按 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 无符号错误超出范围

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

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

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

--工作解决方案--

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

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

【问题讨论】:

链接中提供的解决方案将为您提供帮助mysql Orderby a number, Nulls last 来自the documentation:在执行 ORDER BY 时,如果您执行 ORDER BY ... ASC,则首先显示 NULL 值,如果您执行 ORDER BY ... DESC,则最后显示 NULL 值。我> 您可以尝试使用ORDER BY IFNULL(threat,'z') ASCORDER BY ISNULL(threat) ASC.. 【参考方案1】:

在这种情况下,您必须处理 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)

【讨论】:

@EternalSunShine 如果threat 插入了值7 ..? 在问题中,我们有从 1 到 5 的威胁。如果威胁可以接受任何数字,我们可以使用最大 int number => SELECT ~0 >> 33 as max_int_signed 并将查询更改为 select * from threat_table order by IFNULL(threat, ~0 >> 33)【参考方案2】:

请使用ifnull() 函数。在选择查询中将null 值替换为合适的值。

【讨论】:

【参考方案3】:
SELECT *       
FROM TableName
ORDER BY (CASE
            WHEN ColumnName IS NULL THEN 1 
            ELSE 0 
          END), 
         ColumnName

我希望这行得通。

【讨论】:

【参考方案4】:
ORDER BY column_name IS NULL, column_name ASC

你也可以使用mysqlCOALESCE函数See the documentation here

【讨论】:

【参考方案5】:

尝试将您的价值投射到signed

order by cast(-1 *coalesce(Threat,0) as signed)

coalesce(Threat,0)转换代表提供空值出现在底部。

【讨论】:

以上是关于Mysql的排序顺序的主要内容,如果未能解决你的问题,请参考以下文章

MySql:按父子顺序排序

Mysql中ORDER BY 排序怎么使用?指定顺序和多字段排列

mysql必知必会--排序检索数据

mysql in 排序 也可以按in里面的顺序来排序

Mysql的排序顺序

显式指定mysql查询的排序顺序?