在SQL语句中一起使用CASE和COUNT

时间:2011-12-15 14:52:14

标签: sql sql-server-2008

我需要编写一个可以返回指示三件事的列的SQL语句。这三件事是'实际班级','多班','没有选择班级'。我已经使用了一个函数来为我提供这个,但随着表记录的增长,这种方法的速度减慢了很多。有人可以告诉我如何在不牺牲速度的情况下实现这一点,当记录数量增长时?我在想某种类型的案例可以一起计算,但无法弄明白。

我需要返回的数据看起来像这样。

Student         Classes
Bugs Bunny      Multiple Classes
Daffy Duck      Biology 101
Porky Pig       No Classes Selected
Schema

Student
StudentId int
Name

Class
ClassId int
Name

StudentClass
StudentId
ClassId

3 个答案:

答案 0 :(得分:1)

另一个版本,非常类似于前两个版本;连接次数减少,每个学生最多只能查找一个班级(可能会对真正的大型桌子产生影响)。

SELECT
  xx.Name
  ,case xx.ClassCount
     when 0 then 'No Classes Selected'
     when 1 then cl.Name
     else 'Multiple Classes'
   end  Classes
 from (--  Count classes per student
       select
          st.Name
         ,count(sc.ClassId) ClassCount
         ,max(sc.ClassId)   OneClass  --  If a student has one class, this is it
        from Students st
         left outer join StudentClass sc
          on sc.StudentId = st.StudentId
        group by st.Name) xx
  left outer join Classes cl
   on cl.ClassId = xx.OneClass

(无法调试,希望没有拼写错误......)

(无法调试,希望没有更多拼写错误...)

答案 1 :(得分:0)

您的架构应如下所示

Student
StudentId int
Name

Class
ClassId int
Name

StudentClass
StudentId
ClassId

然后您的查询将如下所示:

select
   s.Name,
   CASE x.ClassCount when 0 then 'No Classes Selected' when 1 then c.Name else 'Multiple Classes'
from
   Student s
   inner join
(select
   StudentId, count(sc.ClassId) as ClassCount
from
   Student s 
   left outer join StudentClass sc on s.StudentId = sc.StudentId
group by
  s.StudentId) x on s.StudentId = x.StudentId
  left outer join StudentClass sc2 on sc2.StudentId = x.StudentId and x.ClassCount = 1
  left outer join Class c on c.ClassId = sc2.ClassId

答案 2 :(得分:0)

我会查看使用子查询来获取学生ID和班级计数,然后再次查找班级名称,只有一个,如:

 Select s.Name,  
     Case s.Count
       When 0 Then 'No Classes Selected' 
       When 1 Then c.className 
       Else 'Multiple Classes' 
     End
From (
    select s.id, s.name, count(cs.id) as Count
    From student s 
    left join studentclass cs on c.studentid = s.id
    group by s.id, s.name
) as s
left join studentclass cs on c.studentid = s.id
left join class c on c.id = cs.classid

当然,我老了,子查询可以被分解成一个公用表表达式(CTE)。