按在 case 表达式中带有别名的计算列排序
Order by calculated column with alias inside case expression
我的 order by
子句在使用带有如下别名的计算列时出现问题:
这个 order by
没有任何问题
declare @Mode int = 1
declare @Sort nvarchar(max) = 'engname'
select top 10 School.Id as EntityId,
School.EnglishName as EntityEnglishName,
School.Name as EntityNativeName,
case
when @Mode = 0 then 0
when @Mode = 1 then 1
when @Mode = 2 then 2
end as ActiveStudents
from V_SchoolMinimized as School
Order By ActiveStudents
以下查询有错误:
Invalid column name 'ActiveStudents'
declare @Mode int = 1
declare @Sort nvarchar(max) = 'engname'
select top 10 School.Id as EntityId,
School.EnglishName as EntityEnglishName,
School.Name as EntityNativeName,
case
when @Mode = 0 then 0
when @Mode = 1 then 1
when @Mode = 2 then 2
end as ActiveStudents
from V_SchoolMinimized as School
Order By
case when @Sort is null then School.Id end,
case when @Sort = 'engname' then ActiveStudents end
如何在条件 order by
子句中使用 ActiveStudents
,如图所示?
因此,虽然您可以在 ORDER BY
子句中使用计算列(但不能在 GROUP BY
等其他子句中使用),但您无法应用进一步的计算或条件 - 它必须准确使用创建时。
有很多方法可以解决这个问题。您使用哪种方法将归结为以下组合:
- 作为开发者,您更清楚哪个选项
- 哪个选项效果更好
- 哪个选项更适合您现有的查询
选项 1:重复逻辑
我不推荐这个选项,因为它违反了 DRY 原则,因此更难维护,更容易出错。
select top 10
S.Id as EntityId
, S.EnglishName as EntityEnglishName
, S.[Name] as EntityNativeName
, case
when @Mode = 0 then 0
when @Mode = 1 then 1
when @Mode = 2 then 2
end as ActiveStudents
from V_SchoolMinimized as S
order by
case when @Sort is null then S.Id end
, case when @Sort = 'engname' then
case
when @Mode = 0 then 0
when @Mode = 1 then 1
when @Mode = 2 then 2
end
end;
其余选项是 sub-query 变体,选择取决于作为开始提供的评论。
选项 2:使用派生的 table sub-query
select top 10
S.Id as EntityId
, S.EnglishName as EntityEnglishName
, S.[Name] as EntityNativeName
, S.ActiveStudents
from (
select *
, case
when @Mode = 0 then 0
when @Mode = 1 then 1
when @Mode = 2 then 2
end as ActiveStudents
from V_SchoolMinimized
) as S
order by
case when @Sort is null then S.Id end
, case when @Sort = 'engname' then S.ActiveStudents end;
选项 3:使用 CTE(常用 Table 表达式)
with cte as (
select *
, case
when @Mode = 0 then 0
when @Mode = 1 then 1
when @Mode = 2 then 2
end as ActiveStudents
from V_SchoolMinimized
)
select top 10
S.Id as EntityId
, S.EnglishName as EntityEnglishName
, S.[Name] as EntityNativeName
, S.ActiveStudents
from cte
order by
case when @Sort is null then S.Id end
, case when @Sort = 'engname' then S.ActiveStudents end;
选项 4:使用 CROSS APPLY
select top 10
S.Id as EntityId
, S.EnglishName as EntityEnglishName
, S.[Name] as EntityNativeName
, A.Students
from V_SchoolMinimized as S
cross apply (
values (
case
when @Mode = 0 then 0
when @Mode = 1 then 1
when @Mode = 2 then 2
end
)
) as A (Students)
order by
case when @Sort is null then S.Id end
, case when @Sort = 'engname' then A.Students end;
注意:我建议让您的 table 别名尽可能简短,1-2 个字符,偶尔 3 个。
我的 order by
子句在使用带有如下别名的计算列时出现问题:
这个 order by
没有任何问题
declare @Mode int = 1
declare @Sort nvarchar(max) = 'engname'
select top 10 School.Id as EntityId,
School.EnglishName as EntityEnglishName,
School.Name as EntityNativeName,
case
when @Mode = 0 then 0
when @Mode = 1 then 1
when @Mode = 2 then 2
end as ActiveStudents
from V_SchoolMinimized as School
Order By ActiveStudents
以下查询有错误:
Invalid column name 'ActiveStudents'
declare @Mode int = 1
declare @Sort nvarchar(max) = 'engname'
select top 10 School.Id as EntityId,
School.EnglishName as EntityEnglishName,
School.Name as EntityNativeName,
case
when @Mode = 0 then 0
when @Mode = 1 then 1
when @Mode = 2 then 2
end as ActiveStudents
from V_SchoolMinimized as School
Order By
case when @Sort is null then School.Id end,
case when @Sort = 'engname' then ActiveStudents end
如何在条件 order by
子句中使用 ActiveStudents
,如图所示?
因此,虽然您可以在 ORDER BY
子句中使用计算列(但不能在 GROUP BY
等其他子句中使用),但您无法应用进一步的计算或条件 - 它必须准确使用创建时。
有很多方法可以解决这个问题。您使用哪种方法将归结为以下组合:
- 作为开发者,您更清楚哪个选项
- 哪个选项效果更好
- 哪个选项更适合您现有的查询
选项 1:重复逻辑
我不推荐这个选项,因为它违反了 DRY 原则,因此更难维护,更容易出错。
select top 10
S.Id as EntityId
, S.EnglishName as EntityEnglishName
, S.[Name] as EntityNativeName
, case
when @Mode = 0 then 0
when @Mode = 1 then 1
when @Mode = 2 then 2
end as ActiveStudents
from V_SchoolMinimized as S
order by
case when @Sort is null then S.Id end
, case when @Sort = 'engname' then
case
when @Mode = 0 then 0
when @Mode = 1 then 1
when @Mode = 2 then 2
end
end;
其余选项是 sub-query 变体,选择取决于作为开始提供的评论。
选项 2:使用派生的 table sub-query
select top 10
S.Id as EntityId
, S.EnglishName as EntityEnglishName
, S.[Name] as EntityNativeName
, S.ActiveStudents
from (
select *
, case
when @Mode = 0 then 0
when @Mode = 1 then 1
when @Mode = 2 then 2
end as ActiveStudents
from V_SchoolMinimized
) as S
order by
case when @Sort is null then S.Id end
, case when @Sort = 'engname' then S.ActiveStudents end;
选项 3:使用 CTE(常用 Table 表达式)
with cte as (
select *
, case
when @Mode = 0 then 0
when @Mode = 1 then 1
when @Mode = 2 then 2
end as ActiveStudents
from V_SchoolMinimized
)
select top 10
S.Id as EntityId
, S.EnglishName as EntityEnglishName
, S.[Name] as EntityNativeName
, S.ActiveStudents
from cte
order by
case when @Sort is null then S.Id end
, case when @Sort = 'engname' then S.ActiveStudents end;
选项 4:使用 CROSS APPLY
select top 10
S.Id as EntityId
, S.EnglishName as EntityEnglishName
, S.[Name] as EntityNativeName
, A.Students
from V_SchoolMinimized as S
cross apply (
values (
case
when @Mode = 0 then 0
when @Mode = 1 then 1
when @Mode = 2 then 2
end
)
) as A (Students)
order by
case when @Sort is null then S.Id end
, case when @Sort = 'engname' then A.Students end;
注意:我建议让您的 table 别名尽可能简短,1-2 个字符,偶尔 3 个。