http://msdn.microsoft.com/en-us/library/ms181765.aspx
我从上面的链接看到下面的sql:
SELECT BusinessEntityID, SalariedFlag
FROM HumanResources.Employee
ORDER BY CASE SalariedFlag WHEN 1 THEN BusinessEntityID END DESC
,CASE WHEN SalariedFlag = 0 THEN BusinessEntityID END;
GO
以下是我得到的一个结果:
BusinessEntityID,SalariedFlag
7,1
5,1
3,1
1,1
2,0
4,0
6,0
8,0
有人可以解释为什么具有相同salariedFlag的记录彼此相邻以及为什么salariedFlag = 1 chunk高于salariedFlag = 0块?
答案 0 :(得分:5)
sort子句等同于以下内容,可能稍微明显一点:
ORDER BY CASE SalariedFlag WHEN 1 THEN BusinessEntityID ELSE null END DESC
,CASE WHEN SalariedFlag = 0 THEN BusinessEntityID ELSE null END;
因此,当SalariedFlag = 1时,第一个排序字段是BusinessEntityID,或者为null 这会将SalariedFlag = 0的所有行组合在一起,因为它们都有一个空的第一个排序字段 SalariedFlag = 1的行将按BusinessEntityID排序。看起来nulls以降序排序最后排序,所以所有SalariedFlag!= 1都是最后一个。
这是主要类型,对于次要排序,发生了同样的事情:
SalariedFlag = 0的所有行都将按BusinessEntityID排序。由于它们的主要排序字段都为空,因此最终将按BusinessEntityID排序。
SalariedFlag!= 0的所有行将与空的二级排序组合在一起。如果这些行的SalariedFlag = 1,则它们已经按主要顺序排序。
如果SalariedFlag只能是0或1,那么这种情况可以(略微)简化为:
ORDER BY CASE SalariedFlag WHEN 1 THEN BusinessEntityID END DESC
, BusinessEntityID;
答案 1 :(得分:2)
通过在SELECT子句中包含CASE WHEN条件,可以很容易地想象它为什么按照这种方式排序:
SELECT BusinessEntityID, SalariedFlag,
CASE SalariedFlag WHEN 1 THEN BusinessEntityID END AS A,
CASE WHEN SalariedFlag = 0 THEN BusinessEntityID END AS B
FROM Employee
ORDER BY CASE SalariedFlag WHEN 1 THEN BusinessEntityID END DESC
,CASE WHEN SalariedFlag = 0 THEN BusinessEntityID END;
输出:
BUSINESSENTITYID SALARIEDFLAG A B
7 1 7 (null)
5 1 5 (null)
3 1 3 (null)
1 1 1 (null)
2 0 (null) 2
4 0 (null) 4
6 0 (null) 6
8 0 (null) 8
SalariedFlag 0保持在一起的原因是,它们都在null下看到(看A列),如果SalariedFlag有另一个值,比如说2号,则完全是另一回事,并且该查询将不再起作用,那些拥有相同旗帜的人不一定会彼此相邻。
NULL排序首先,如果指定DESC,它将排序最后。
实时测试:http://www.sqlfiddle.com/#!3/1b849/13
认识到查询的CASE WHEN的THEN使用的是整数类型的BusinessEntityID,您可以执行以下查询来实现相同的效果;并且因为它使用SalariedFlag作为分隔符,所以以下查询 可能 更快,因为您没有在ORDER BY上使用条件。您只需切换SalariedFlag并对其进行排序:
-- just to visualize things up
SELECT BusinessEntityID, SalariedFlag,
A = BusinessEntityID * SalariedFlag,
B = BusinessEntityID * (SalariedFlag ^ 1)
FROM Employee
ORDER BY A DESC, B
-- in actual you do this:
SELECT BusinessEntityID, SalariedFlag
FROM Employee
ORDER BY BusinessEntityID * SalariedFlag DESC, BusinessEntityID * (SalariedFlag ^ 1)
鉴于此数据:
CREATE TABLE [Employee]
([BusinessEntityID] int, [SalariedFlag] int);
INSERT INTO [Employee]
([BusinessEntityID], [SalariedFlag])
VALUES
(10, 1),
(5, 1),
(9, 1),
(1, 1),
(2, 0),
(7, 0),
(6, 0),
(8, 0);
这是输出:
BUSINESSENTITYID SALARIEDFLAG A B
10 1 10 0
9 1 9 0
5 1 5 0
1 1 1 0
2 0 0 2
6 0 0 6
7 0 0 7
8 0 0 8
答案 2 :(得分:1)
当标记为BusinessEntityID
时,您首先按1
排序,然后在标记为BusinessEntityID
时按0
解析关联。这是因为当CASE
不是null
时,第一个SalariedFlag
表达式的计算结果为1
,因此标记为0
的所有记录都将移至记录之后标志为1
。
答案 3 :(得分:0)
尝试在您选择的值列表中包含case语句。它应该有助于澄清排序实际发生的值。