使用CASE WHEN时,ORDER BY无法正常工作,但是如果没有,则可以正常工作吗?

时间:2019-04-30 19:26:26

标签: sql-server tsql

我有以下选择语句,在这里我尝试以特定方式(特别是部门的层次)对结果进行排序。但是,当我添加案例时,我的ORDER BY停止工作并给我一个错误:

  如果

ORDER BY项目必须出现在选择列表中   包含UNION,INTERSECT或EXCEPT运算符。

我不知道为什么会这样,因为我在每个SELECT语句中都选择了所有内容。

Select * FROM AccountAdminTable Where CollegeCode = 'A10' AND AdminLevel LIKE 'Account Administrator'
Union
Select * FROM AccountAdminTable Where CollegeCode = 'A10' AND AdminLevel LIKE 'Department Head/Director'
Union
Select * FROM AccountAdminTable Where CollegeCode = 'A10' AND AdminLevel LIKE 'Dean/Vice President'
Order By AdminLevel ASC

这不起作用:

Select * FROM AccountAdminTable Where CollegeCode = 'A' AND AdminLevel LIKE 'Account Administrator'
Union
Select * FROM AccountAdminTable Where CollegeCode = 'A' AND AdminLevel LIKE 'Department Head/Director'
Union
Select * FROM AccountAdminTable Where CollegeCode = 'A' AND AdminLevel LIKE 'Dean/Vice President'
Order By Case
    When AdminLevel = 'Account Administrator' Then 1
    When AdminLevel = 'Department Head/Director' Then 2
    When AdminLevel = 'Dean/Vice President' Then 3
    Else 4 End ASC

任何帮助将不胜感激!以下是一些示例数据。

College Code| AdminLevel               | Name
A           | Account Administrator    | Bob
A           | Department Head/Director | Tim
A           | Dean/Vice President      | Jeff
B           | Account Administrator    | Gary
B           | Department Head/Director | Phil
B           | Dean/Vice President      | John
C           | Account Administrator    | Bill
C           | Account Administrator    | Larry

3 个答案:

答案 0 :(得分:6)

您知道,这里确实根本不需要使用UNION。由于您所有的SELECTS都来自同一张表,因此您可以执行此操作(请注意,下面我的伪代码中使用的缩写。显然,您的代码中使用了正确的值):

Select * FROM AccountAdminTable 
Where CollegeCode = 'A'
AND AdminLevel IN ('Account Administrator','Dept HD','Dean/VP')
ORDER BY CASE {Your CASE Expression}

答案 1 :(得分:4)

您有2个选择:

  • 使用派生表在ORDER BY中使用CASE。
SELECT *
FROM(
         Select * FROM AccountAdminTable Where CollegeCode = 'A' AND AdminLevel LIKE 'Account Administrator'
        Union
        Select * FROM AccountAdminTable Where CollegeCode = 'A' AND AdminLevel LIKE 'Department Head/Director'
        Union
        Select * FROM AccountAdminTable Where CollegeCode = 'A' AND AdminLevel LIKE 'Dean/Vice President'
        )t
Order By Case 
        When AdminLevel = 'Account Administrator' Then 1
        When AdminLevel = 'Department Head/Director' Then 2
        When AdminLevel = 'Dean/Vice President' Then 3
        Else 4 End ASC;

*或添加定义订单的列。

Select *, 1 AS OrderCol FROM AccountAdminTable Where CollegeCode = 'A' AND AdminLevel LIKE 'Account Administrator'
Union
Select *, 2 AS OrderCol FROM AccountAdminTable Where CollegeCode = 'A' AND AdminLevel LIKE 'Department Head/Director'
Union
Select *, 3 AS OrderCol FROM AccountAdminTable Where CollegeCode = 'A' AND AdminLevel LIKE 'Dean/Vice President'
Order By OrderCol;

无论哪种方式,您都可能希望将UNION更改为UNION ALL以提高性能。除非您实际上要消除重复项。

答案 2 :(得分:2)

另一个编写查询的选项是:

SELECT AccountAdminTable.*
FROM AccountAdminTable
INNER JOIN (VALUES
    (1, 'Account Administrator'),
    (2, 'Dept HD'),
    (3, 'Dean/VP')
) AS vlist(Sort, AdminLevel) ON AccountAdminTable.AdminLevel = vlist.AdminLevel
WHERE CollegeCode = 'A'
ORDER BY vlist.Sort

或者更好的是,为管理员级别创建一个表,并通过外键进行引用。