如何强制特定值出现在 SQL 排序中的顶部?

问题描述 投票:0回答:1

我正在努力按升序对名称列表进行排序,同时确保特定值始终出现在列表的顶部。我有以下 SQL 查询:

SELECT province_name
FROM province_names
ORDER BY
  (CASE WHEN province_name = 'Ontario' THEN 0 ELSE 1 END),
  province_name;

此查询成功地将“Ontario”放置在顶部,后面是按升序排序的其他省份名称。但是,我想了解使该方法发挥作用的底层逻辑和机制。此外,我有兴趣了解实现此结果的替代方法。

示例上下文:

考虑一个包含以下数据的表

province_names

省名
艾伯塔省
魁北克
安大略省
马尼托巴省
不列颠哥伦比亚省

所需输出:

省名
安大略省
艾伯塔省
不列颠哥伦比亚省
马尼托巴省
魁北克

任何见解或解释将不胜感激!

sql
1个回答
0
投票

为什么这有效?

答案相对简单。您的

ORDER BY
子句可以被认为是
ORDER BY condition1, condition2
,其中
condition1
优先于
condition2

在您的情况下,

condition1
(CASE WHEN province_name = 'Ontario' THEN 0 ELSE 1 END),
,这意味着该表达式对于
0
计算为
Ontario
,对于所有其他省份计算为
1
。您可以将其视为数据库未按评估表达式的一列进行排序:

省名 评估表达式
艾伯塔省 1
魁北克 1
安大略省 0
马尼托巴省 1
不列颠哥伦比亚省 1

现在,由于默认排序顺序是升序,我们希望按这个假想的

evaluated_expression
列进行排序,安大略省将位于顶部,因为它是最小值,所有其他值都将排在它之后。

由于表中的所有其他行都具有相同的值,因此就第一个条件而言,它们具有“相同的顺序”。现在,我们将评估第二个条件,即 province_name。这将根据您的数据库

排序规则
按字母升序排序。 其他方法

还有很多其他方法。我现在能想到的一个是:

SELECT province_name FROM ( SELECT 0, province_name FROM province_names WHERE province_name = 'Ontario' UNION ALL SELECT 1, province_name FROM province_names WHERE province_name <> 'Ontario' ORDER BY 0, province_name) subquery;

这里的想法是有一个子查询

查询应该位于顶部的记录并添加具有常量值的列
    0
  1. 使用 
  2. UNION ALL
  3. 追加到结果集
    查询不应该位于顶部的所有其他记录,并添加一个具有常量值 
  4. 1
  5. 的列,然后按
    0
    排序,然后
    province_name
    给出以下结果:
    
    
省名安大略省艾伯塔省不列颠哥伦比亚省马尼托巴省魁北克
0
1
1
1
1
现在您已经有了订单,但不幸的是您也不需要此列。为了摆脱这个问题,我们需要主查询,它只需选择上表的第一列,您就可以获得所需的结果。

© www.soinside.com 2019 - 2024. All rights reserved.