【发布时间】:2021-06-26 21:44:36
【问题描述】:
我们看下表:
| col1 | col2 |
| -------- | -------------- |
| 1 | NULL |
| 23 | c |
| 73 | NULL |
| 43 | a |
| 3 | d |
假设你想这样排序:
| col1 | col2 |
| -------- | -------------- |
| 1 | NULL |
| 73 | NULL |
| 43 | a |
| 23 | c |
| 3 | d |
使用以下代码,这几乎是微不足道的:
SELECT *
FROM dbo.table1
ORDER BY col2;
但是,按照以下非标准方式对其进行排序并不容易:
| col1 | col2 |
| -------- | -------------- |
| 43 | a |
| 23 | c |
| 3 | d |
| 1 | NULL |
| 73 | NULL |
我用下面的代码做到了
SELECT *
FROM dbo.table1
ORDER BY CASE WHEN col2 IS NULL THEN 1 ELSE 0 END, col2;
您能向我解释一下 1) 为什么 和 2) 这个查询是如何工作的吗?令我烦恼的是,CASE 语句返回 1 或 0,这意味着将执行 ORDER BY 1, col2 或 ORDER BY 0, col2。但是下面的代码给了我一个错误:
SELECT *
FROM dbo.table1
ORDER BY 0, col2;
然而,整体说法是有效的。为什么?
【问题讨论】:
-
按数字排序(序数排序)是按该序数位置的列排序而不是值 0。但是列号从 1 开始,因此按 0 排序失败的原因.这是一种老式的、不推荐的订购方式。
-
请注意,
CASE是一个表达式,因此 SQL 按该值排序。但是,对于常量表达式,会使用 SELECT 子句中列的序号。 -
因为当您添加
case表达式(或任何计算)时,它不再被视为序数。 -
它被视为自然数据类型,即 int。如果您考虑一下,
ORDER BY 0对每一行都有相同的值。ORDER BY CASE WHEN col2 IS NULL THEN 1 ELSE 0 END并不(不一定)对每一行都具有相同的值。有些行可以为 0,而其他行可以为 1,因此您按 int 排序(根据需要使用 desc 或 asc)。
标签: sql sql-server tsql sql-order-by case