我需要编写一个可以返回指示三件事的列的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
答案 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)。