SQL:显示全名+按主题过滤

时间:2012-07-23 15:35:36

标签: sql sql-server-2008 inner-join not-exists

以下是我的表格中的以下记录:

EnrollStudents

EnrollID     StudentID  SubjID
1            1          1
2            1          2
3            1          3
4            2          1
5            3          2

学生

StudentID     UserID     YearID     FirstName     LastName
1             1          1          John          Doe
2             3          1          Peter         Pan
3             7          1          Isaac         Newton

受试者

SubjID     SubjCode     YearID
1          English      1
2          Math         1
3          Science      1

,输出应该是......

StudentID     FullName
2             Peter Pan
3             Isaac Newton

我能够提出以下SQL语句(感谢Ic.

SELECT s.StudentID, s.FirstName + ' ' s.LastName AS FullName 
FROM Students AS s
LEFT OUTER JOIN EnrollStudents AS es ON s.StudentID = es.StudentID
GROUP BY s.StudentID, s.FirstName, s.LastName 
HAVING COUNT(DISTINCT(es.SubjID)) < (SELECT COUNT(*) FROM Subjects)

有没有办法按主题过滤查询?假设我选择英语,只有艾萨克牛顿可以报名参加。

3 个答案:

答案 0 :(得分:3)

您可以使用更简单的查询来查找未注册主题的学生,例如:

select StudentID,
    FirstName + ' ' + LastName as FullName
from Students
where StudentID not in (
    select es.StudentID
    from EnrollStudents es
    inner join Subjects s on es.SubjID = s.SubjID
    where s.SubjCode = 'English'
)

SQL Fiddle Example

您也可以将其写为左连接,如下所示:

select s.StudentID,
    s.FirstName + ' ' + s.LastName as FullName
from Students s
left outer join (
    select distinct es.StudentID
    from EnrollStudents es
    inner join Subjects s on es.SubjID = s.SubjID
    where s.SubjCode = 'English'
) ss on s.StudentID = ss.StudentID
where ss.StudentID is null

答案 1 :(得分:1)

我认为您的查询不必要地复杂化。例如,您不需要左外连接。此外,您可以省略having子句中的子查询:

SELECT s.StudentID, s.FirstName + ' ' s.LastName AS FullName
FROM Students AS s JOIN
     EnrollStudents AS es
    ON s.StudentID = es.StudentID
GROUP BY s.StudentID, s.FirstName, s.LastName
HAVING COUNT(DISTINCT(es.SubjID)) < COUNT(es.SubjID)

只获得英语:

SELECT s.StudentID, s.FirstName + ' ' s.LastName AS FullName
FROM EnrollStudents AS es join
     Students AS s
     ON s.StudentID = es.StudentID join
     Subjects su
     on es.subjid = su.subjid
where su.subjcode in ('English')
GROUP BY s.StudentID, s.FirstName, s.LastName
HAVING COUNT(DISTINCT(es.SubjID)) < COUNT(es.SubjID)

当仅限于一个主题时,我认为“拥有”条款是无关紧要的。你能描述一下你想让查询做什么吗?

答案 2 :(得分:0)

这在MySQL中适用于我。不得不以不同的方式连接,但工作就像一个魅力

SELECT Students.StudentID, CONCAT(Students.FirstName, ' ', Students.LastName) AS FullName
FROM Students, Enrollstudents, Subjects
WHERE Subjects.SubjID = 2 <--- HERE IS THE BIT YOU CHANGE TO FILTER
AND   EnrollStudents.SubjID = Subjects.SubjID
AND   Students.StudentID = Enrollstudents.StudentID

使用concat方法:

SELECT Students.StudentID, Students.FirstName + ' ' Students.LastName AS FullName
FROM Students, Enrollstudents, Subjects
WHERE Subjects.SubjID = 2
AND   EnrollStudents.SubjID = Subjects.SubjID
AND   Students.StudentID = Enrollstudents.StudentID

注意:您可以对所需的WHERE子句执行任何操作。要让所有未注册某个主题的人,请将第四行更改为:

AND   EnrollStudents.SubjID <> Subjects.SubjID

AND NOT  EnrollStudents.SubjID = Subjects.SubjID

(我认为)