Sql server 使用CASE时不工作,但在没有它的情况下工作?

Sql server 使用CASE时不工作,但在没有它的情况下工作?,sql-server,tsql,Sql Server,Tsql,我在下面的select语句中尝试以特定的方式对结果进行排序,特别是部门的层次结构。但是,当我添加案例时,我的ORDER BY停止工作,并出现错误: 如果语句 包含UNION、INTERSECT或EXCEPT运算符 我不知道为什么会发生这种情况,因为我在每个SELECT语句中选择all Select * FROM AccountAdminTable Where CollegeCode = 'A10' AND AdminLevel LIKE 'Account Administrator' Union

我在下面的select语句中尝试以特定的方式对结果进行排序,特别是部门的层次结构。但是,当我添加案例时,我的ORDER BY停止工作,并出现错误:

如果语句 包含UNION、INTERSECT或EXCEPT运算符

我不知道为什么会发生这种情况,因为我在每个SELECT语句中选择all

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
您有两种选择:

  • 使用派生表在ORDER BY中使用大小写
*或添加定义顺序的列

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以提高性能。除非你真的在消除重复项。

你知道,在这里你根本不需要使用联合。由于您所有的选择都来自同一个表,您可以这样做(注意,下面我的伪代码中使用了缩写。显然,在代码中使用正确的值):


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

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

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

错误很明显。你是按箱子订购的。因为您使用的是UNION,所以必须在每个选择中包含大小写。使用子查询或CTE,并在外部查询中排序您可能也想使用
UNION ALL
,因为
UNION
将导致数据引擎只返回不同的结果;这可能是一个代价高昂的操作。旁白:您可以使用简单的案例,而不是搜索案例,因为您只是根据一系列字符串文本检查单个列的值:
case AdminLevel当“帐户管理员”时为1当“部门主管/主管”时为2…
。但您可能只想使用第二种方法,因为当从现在起几天、几周、几个月内对自己的代码进行QA;你会更好地了解order by在做什么以及它的价值。老实说,这里的联盟只是一个性能障碍。每个查询都是同一个表。@SeanLange我同意,除非在远程情况下,表中存在重复项。当然,这意味着一个更大的问题。确实如此,但一个简单的方法可以解决这个问题。
Select * FROM AccountAdminTable 
Where CollegeCode = 'A'
AND AdminLevel IN ('Account Administrator','Dept HD','Dean/VP')
ORDER BY CASE {Your CASE Expression}
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