我有一张学生桌和一张报名表;学生可以拥有多个可以处于活动状态或不活动状态的注册记录。
我希望获得一个具有单个学生记录的选择,并指示该学生是否有活跃的注册。
我考虑过在内联UDF中执行此操作,该内联UDF在注册表的连接中使用学生ID,但我想知道是否有更好的方法可以在单个select语句中执行此操作。
UDF调用可能类似于:
Select Student_Name,Student_Email,isEnrolled(Student_ID) from Student
使用一个SQL语句的替代方案可能是什么样的?
答案 0 :(得分:1)
select Student_Name,
Student_Email,
(select count(*)
from Enrollment e
where e.student_id = s.student_id
) Number_Of_Enrollments
from Student e
将获得入学人数,这应该会有所帮助。
答案 1 :(得分:1)
为什么不加入二级选择?与其他解决方案不同,这不会为返回的每一行触发子查询,而是一次性收集所有人的注册数据。语法可能不太正确,但你应该明白这个想法。
SELECT
s.student_name,
s.student_email,
IsNull( e.enrollment_count, 0 )
FROM
Students s
LEFT OUTER JOIN (
SELECT
student_id,
count(*) as enrollment_count
FROM
enrollments
WHERE
active = 1
GROUP BY
student_id
) e
ON s.student_id = e.student_id
从注册中选择也可以重做为一个函数,它返回一个表供您加入。
CREATE FUNCTION getAllEnrollmentsGroupedByStudent()
RETURNS @enrollments TABLE
(
student_id int,
enrollment_count int
) AS BEGIN
INSERT INTO
@enrollments
(
student_id,
enrollment_count
) SELECT
student_id,
count(*) as enrollment_count
FROM
enrollments
WHERE
active = 1
GROUP BY
student_id
RETURN
END
SELECT
s.student_name,
s.student_email,
e.enrollment_count
FROM
Students s
JOIN
dbo.getAllEnrollmentsGroupedByStudent() e
ON s.student_id = e.student_id
修改强>
Renze de Waal纠正了我糟糕的SQL!
答案 2 :(得分:0)
尝试这样的事情:
SELECT Student_Name, Student_Email, CAST((SELECT TOP 1 1 FROM Enrollments e WHERE e.student_id=s.student_id) as bit) as enrolled FROM Student s
我认为你也可以在select中使用exists语句但不是肯定的
答案 3 :(得分:0)
尽量避免使用udfs或子查询,它们是性能杀手。 banjolity似乎有一个很好的解决方案,因为它使用派生表而不是UDF或subselect。
答案 4 :(得分:0)
select students.name,
decode(count(1), 0, "no enrollments", "has enrollments")
from students, enrollments
where
students.id = enrollments.sutdent_id and
enrollments.is_active = 1 group by students.name
当然,用您的数据库使用的函数(或case语句)替换解码。