11

我的 SQL 查询有问题

我想选择 DISTINCT StudentGroups(SG) 但查询给了我一些重复

这是我的查询

SELECT      DISTINCT(SG.SGID), en.EnrollmentID, CR.Name AS Course, INS.Name as Instructor,
                S.Session, SG.StartTime, SG.EndTime, EN.CreateDate

    FROM        StudentGroups SG inner JOIN Enrollments EN ON SG.SGID = EN.SGID
                JOIN Courses CR ON SG.CourseID = CR.CourseID
                JOIN Class CL ON SG.ClassID = CL.ClassID
                JOIN Instructors INS ON SG.InstructorID = INS.InstructorID
                JOIN Sessions S ON SG.SessionID = S.SessionID

    WHERE       EN.SGID NOT IN ( SELECT SGID FROM Enrollments
                            WHERE StudentID = 45

更新

这个查询给了我以下数据

在此处输入图像描述

但我不想重复 SGID

4

2 回答 2

15

DISTINCT始终适用于返回的所有列。在一列周围加上括号对其行为没有影响。

如果您希望结果仅包含 的唯一值SG.GID,则可以改用GROUP BY子句——但是您必须确定一些规则,以便在其他列中返回哪些值。您可以使用 、 、 、 等聚合函数来执行此操作MIN()MAX()简化COUNT()示例SUM()

SELECT  SG.SGID,
        MIN(SG.START_TIME),              --the lowest start time for this sgid.
        COUNT(DISTINCT en.EnrollmentID)  --the unique enrollments for this sgid.
    FROM StudentGroups SG 
    INNER JOIN Enrollments EN ON SG.SGID = EN.SGID
    GROUP BY SG.SGID;

在原始查询中连接多个表时,在计算和求和时必须小心,因为连接中的重复项可能会给您不正确的结果。

另一种选择是使用ROW_NUMBER()为每个返回一行SGID

SELECT * FROM (
    SELECT  SG.SGID,
            SG.START_TIME, 
            en.EnrollmentID,
            ROW_NUMBER() OVER (PARTITION BY SGID ORDER BY SG.START_TIME) as RN
        FROM StudentGroups SG 
        INNER JOIN Enrollments EN ON SG.SGID = EN.SGID
    )
    WHERE RN = 1;

这对每个 的行进行编号SGID,从 1 开始并按 的值排序SG.START_TIME。它将返回每行具有最早开始时间的一行SGID。如果多行具有相同的开始时间,它将选择其中任何一个,或多或少随机。您可以向ORDER BY子句添加更多字段以进一步定义返回哪些行。

于 2013-02-21T10:19:55.717 回答
6

当 DISTINCT 不适用于您想要的输出时,请使用 GROUP BY 子句。

于 2013-10-09T06:42:01.560 回答