我正在努力按升序对名称列表进行排序,同时确保特定值始终出现在列表的顶部。我有以下 SQL 查询:
SELECT province_name
FROM province_names
ORDER BY
(CASE WHEN province_name = 'Ontario' THEN 0 ELSE 1 END),
province_name;
此查询成功地将“Ontario”放置在顶部,后面是按升序排序的其他省份名称。但是,我想了解使该方法发挥作用的底层逻辑和机制。此外,我有兴趣了解实现此结果的替代方法。
考虑一个包含以下数据的表
province_names
:
省名 |
---|
艾伯塔省 |
魁北克 |
安大略省 |
马尼托巴省 |
不列颠哥伦比亚省 |
省名 |
---|
安大略省 |
艾伯塔省 |
不列颠哥伦比亚省 |
马尼托巴省 |
魁北克 |
任何见解或解释将不胜感激!
答案相对简单。您的
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
UNION ALL
1
0
排序,然后 province_name
给出以下结果:
0 | |
1 | |
1 | |
1 | |
1 |