【问题标题】:SQL: Display Full Name + Filter By SubjectSQL:显示全名+按主题过滤
【发布时间】:2012-07-21 21:05:58
【问题描述】:

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

注册学生

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)

有没有一种方法可以按主题过滤查询?假设我选择英语,只有 Isaac Newton 可以注册该科目。

【问题讨论】:

  • 您使用的是什么 dbms + 版本?
  • @TimSchmelter SQL Server 2008

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    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)
    

    当仅限于单个主题时,我认为“拥有”从句是无关紧要的。您能描述一下您希望查询做什么吗?

    【讨论】:

    • 我想显示尚未注册某个科目的学生的 StudentID 和全名 (EnrollStudents)。我应该能够放置 WHERE 子句,因为我想过滤每个主题的显示。
    【解决方案3】:

    这在 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
    

    (我认为)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-07
      • 1970-01-01
      • 2023-01-26
      • 1970-01-01
      • 1970-01-01
      • 2010-10-14
      • 2023-01-18
      • 2019-08-23
      相关资源
      最近更新 更多