精炼SQL查询 -

时间:2017-08-08 19:38:37

标签: tsql sql-server-2012

我正在制作商店程序,以显示基于2个标准的课程列表: 1.不需要课程的管理员 2.需要课程的学生

我已经让商店的程序得以运作;但是,我想改进它并使其更具可读性。我添加了一个case语句,但是我收到错误“Subquery返回的值超过1。这是不允许的”。我很感激一些反馈。

DECLARE @ROLEID INT = 1;
select *
from Courses
where courseID in (
  case when @ROLEID = 1 then (select coursedID From Department d where d.DepartmentName = 'Accounting') --a ROLEID 1 IS AN ADMINISTRATOR, so there will be several course ids returned
  else (select coursedID From Department d where d.DepartmentName = 'Accounting' and d.CourseId = 'A101') 
)

iF @ROLEID = 1)
BEGIN
    APPROPPRIATE QUERY HERE
END ELSE 
BEGIN 
    APPROPPRIATE QUERY HERE
END

1 个答案:

答案 0 :(得分:2)

case仅适用于标量值,而不适用于整个结果集。因此,当您执行case when @ROLEID = 1 then (...<select query>...)时,它的根本不匹配,因为案例需要单个值,但返回的是一整套数据。

您可以将案例陈述放在内部查询中

select *
from Courses
where CourseId in (select CourseId
                   from Department
                   where DepartmentName = 'Accounting'
                       and CourseId = case when @RoleId = 1 then CourseId else 'A101' end)

或者像这样做

select *
from Courses
where CourseId in (select CourseId
                   from Department
                   where DepartmentName = 'Accounting'
                       and @RoleId = 1 or CourseId = 'A101')

然而两者都会受到错误的查询计划的影响,因为一个查询将使用@RoleId而另一个将使用列值。为了提高性能,从长远来看,将它们分成单独的语句可能会更好

if @RoleId = 1
    select *
    from courses
    where DepartmentName = 'Accounting'
else
    select *
    from courses
    where CourseId = 'A101'
        and DepartmentName = 'Accounting'