用于ORDER BY子句的CASE WHEN语句

70

我正在使用SQL Server 2008 R2。

我希望对表中的记录进行基于优先级的排序。因此,我在ORDER BY子句中使用了CASE WHEN语句。ORDER BY子句如下:

ORDER BY 
CASE WHEN TblList.PinRequestCount <> 0 THEN TblList.PinRequestCount desc, TblList.LastName ASC, TblList.FirstName ASC, TblList.MiddleName ASC END, 
CASE WHEN TblList.HighCallAlertCount <> 0 THEN TblList.HighCallAlertCount desc, TblList.LastName ASC, TblList.FirstName ASC, TblList.MiddleName ASC END,
Case WHEN TblList.HighAlertCount <> 0 THEN TblList.HighAlertCount DESC, TblList.LastName ASC, TblList.FirstName ASC, TblList.MiddleName ASC END,
CASE WHEN TblList.MediumCallAlertCount <> 0 THEN TblList.MediumCallAlertCount DESC, TblList.LastName ASC, TblList.FirstName ASC, TblList.MiddleName ASC END,
Case WHEN TblList.MediumAlertCount <> 0 THEN TblList.MediumAlertCount DESC, TblList.LastName ASC, TblList.FirstName ASC, Patlist.MiddleName ASC END

但它显示“关键字'desc'附近有语法错误”

有什么解决方案吗?

此外,我可以拥有:

TblList.PinRequestCount <> 0 and TblList.HighCallAlertCount <> 0 and
TblList.HighAlertCount <> 0` and TblList.MediumCallAlertCount <> 0 and  
TblList.MediumAlertCount <> 0 

同时。


你能展示一下完整的查询吗? - Shann
你可以写 select * From TblList。 - Dev
你的查询中应该有case语句,对吧? - Shann
你能展示一个例子吗? - alzaimar
4个回答

102
CASE是一个表达式 - 它会返回一个标量值(每行一条)。它不能返回其他语句的解析树的复杂部分,比如SELECT语句的ORDER BY子句。看起来你只需要:
ORDER BY 
CASE WHEN TblList.PinRequestCount <> 0 THEN TblList.PinRequestCount END desc,
CASE WHEN TblList.HighCallAlertCount <> 0 THEN TblList.HighCallAlertCount END desc, 
Case WHEN TblList.HighAlertCount <> 0 THEN TblList.HighAlertCount END DESC,
CASE WHEN TblList.MediumCallAlertCount <> 0 THEN TblList.MediumCallAlertCount END DESC,
Case WHEN TblList.MediumAlertCount <> 0 THEN TblList.MediumAlertCount END DESC,
TblList.LastName ASC, TblList.FirstName ASC, TblList.MiddleName ASC

或者可能是:

ORDER BY 
CASE
   WHEN TblList.PinRequestCount <> 0 THEN TblList.PinRequestCount
   WHEN TblList.HighCallAlertCount <> 0 THEN TblList.HighCallAlertCount
   WHEN TblList.HighAlertCount <> 0 THEN TblList.HighAlertCount
   WHEN TblList.MediumCallAlertCount <> 0 THEN TblList.MediumCallAlertCount
   WHEN TblList.MediumAlertCount <> 0 THEN TblList.MediumAlertCount
END desc,
TblList.LastName ASC, TblList.FirstName ASC, TblList.MiddleName ASC

由于你 a) 没有解释你希望实现的实际排序顺序,以及 b) 没有提供任何样本数据和期望结果,所以很难确定上述哪个(或其他)是你正在寻找的内容。我们需要从样本数据和期望结果中尝试推断出你要实现的实际排序顺序。


这可能是我们正在寻找的答案:

ORDER BY 
CASE
   WHEN TblList.PinRequestCount <> 0 THEN 5
   WHEN TblList.HighCallAlertCount <> 0 THEN 4
   WHEN TblList.HighAlertCount <> 0 THEN 3
   WHEN TblList.MediumCallAlertCount <> 0 THEN 2
   WHEN TblList.MediumAlertCount <> 0 THEN 1
END desc,
CASE
   WHEN TblList.PinRequestCount <> 0 THEN TblList.PinRequestCount
   WHEN TblList.HighCallAlertCount <> 0 THEN TblList.HighCallAlertCount
   WHEN TblList.HighAlertCount <> 0 THEN TblList.HighAlertCount
   WHEN TblList.MediumCallAlertCount <> 0 THEN TblList.MediumCallAlertCount
   WHEN TblList.MediumAlertCount <> 0 THEN TblList.MediumAlertCount
END desc,
TblList.LastName ASC, TblList.FirstName ASC, TblList.MiddleName ASC

在这种情况下,序列没有得到维护。我想要 PinRequestCount<>0 记录置于顶部,并按照 FirstName、LastName 和 MiddleName 的升序排序。然后 HighCallAlertCount 记录 <>0 并按照 FirstName、LastName 和 MiddleName 的计数升序排序。然后 HighAlertCount <>0 并按照 FirstName、LastName 和 MiddleName 的升序排序等等... - Dev
@Dev - 会有任何一行数据出现这样的情况,即多个“Count”列不等于0吗? - Damien_The_Unbeliever
同时,我所指定的每个列的降序排序值都可以不等于零。 - Dev
@Dev - 我已经添加了一个新的猜测 - 就像我说的那样,如果您的问题实际上提供了关于您要实现的内容信息,那将更容易些。 - Damien_The_Unbeliever
好的,让我给您提供一些样本数据和期望的结果。 - Dev
抱歉,我之前不知道可以在回答中进行编辑而是评论。我认为你的最后一个解决方案是有效的.. :) 让我多测试一下。 :) - Dev

21

这里有另一个简单的例子,来自这里

SELECT * FROM dbo.Employee
ORDER BY 
 CASE WHEN Gender='Male' THEN EmployeeName END Desc,
 CASE WHEN Gender='Female' THEN Country END ASC

死链,应该定义性别,如果关键字来自后端,例如 ${sort_by} = 'alphabetically' THEN name END ASC。这会在 Psql 中产生错误,没有这样的列。 - Lalit Fauzdar

3

也许你可以使用 WITH 子句:

WITH request AS (
    SELECT id
         , CASE
               WHEN a > 100 THEN 1
               ELSE 0
        END AS example
    FROM table
)
SELECT *
FROM request
ORDER BY example DESC

它也适用于 WHERE 子句。


-5
declare @OrderByCmd  nvarchar(2000)
declare @OrderByName nvarchar(100)
declare @OrderByCity nvarchar(100)
set @OrderByName='Name'    
set @OrderByCity='city'
set @OrderByCmd= 'select * from customer Order By '+@OrderByName+','+@OrderByCity+''
EXECUTE sp_executesql @OrderByCmd 

2
欢迎来到Stack Overflow!我已经编辑了您的答案;通过将代码缩进4个空格,它被放置在“代码markdown”中。我建议您在答案中添加一些解释,解释这段代码如何解决问题。您可以[编辑]解释到您的答案中。祝你好运! - S.L. Barth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接