2011-12-15 83 views
1

我需要编写一个SQL语句,它可以返回指示三件事情的列。三件事是'实际的班级','多个班级','没有选择班级'。我已经使用了一个函数来获取这个,但随着表记录的增长,这种方法有所减慢。有人能告诉我如何做到这一点,而不会牺牲速度,当记录的数量增长?我认为某种类型的案件可以统计在一起,但无法弄清楚。在SQL Statement中一起使用CASE和COUNT

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

 
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

你能编辑的问题,包括模式/基础数据对应于您提供的输出? – 2011-12-15 14:53:51

+2

你可以发布你已经使用的函数吗(一切都有点假设,没有更多关于表结构的想法) – 2011-12-15 14:53:58

+0

对不起,忘记了模式。我的模式与第一个答案中发布的相同。 – 2011-12-15 15:55:26

回答

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 

(不能调试,幸而没有错别字......)

(不能调试,幸而没有更多错别字......)

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 
+0

对不添加架构,但你展示的是我所拥有的。不幸的是,我得到'无效的列名称ClassCount'。 – 2011-12-15 15:48:36

0

我想看看使用子查询,以获得学生证当只有一个时,班级计数再次查找班级名称,如下所示:

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)。