SQL返回重复的列值

问题描述 投票:1回答:2

我想做的事情:只显示唯一的课程ID,其中每个课程ID显示1名学生的项目名称和最新的项目日志。

例:

+----------+-------------+-----------------+------------------+
| CourseID | StudentName | ProjectName     | LatestLog        |
+----------+-------------+-----------------+------------------+
| 1        | Bob         | Bob's Project   | 01/09/2017 09:15 |
+----------+-------------+-----------------+------------------+
| 2        | Tim         | Tim's Project   | 02/10/2017 13:00 |
+----------+-------------+-----------------+------------------+
| 3        | Billy       | Billy's Project | 02/12/2017 12:45 |
+----------+-------------+-----------------+------------------+

这些是我的数据库表关系:

  • 一门课程有很多学生。 (1对多)
  • 一个学生有一个学生项目。 (1比1)
  • 学生项目有很多项目日志。 (1对多)

对于每个课程,我想在LogDate(DATETIME值)上使用MAX以及与该日志相关的学生和项目名称查找最近提交的项目日志。 (编辑:不是每个属于该课程的学生,只是提交下一个项目日志进行审核的学生姓名和项目名称,即可能使用MAX功能的最新日期的日志)

此SQL查询的问题在于它返回了许多重复的课程ID,并且每个日志的每个学生和项目名称都将被返回。

我希望我已经清楚地描述了这个问题。我怎样才能解决这个问题?谢谢!

SELECT Course.ID, -- INT
       Student.Name, -- VARCHAR(50)
       StudentProjects.Name, -- VARCHAR(50)
       MAX(ProjectLogs.LogDate) AS LogDate -- DATETIME

FROM ProjectLogs INNER JOIN
     Student ON Student.ID = ProjectLogs.StudentID INNER JOIN
     StudentProjects ON StudentProjects.ID = Student.ProjectID INNER JOIN
     Course ON Course.ID = Student.CourseID

GROUP BY Course.ID, Student.Name, StudentProjects.Name
sql select duplicates
2个回答
1
投票

这就是你要找的东西:

select Id as course_id,
       student_name,
       student_name,
       project_name,
       LogDate
 from (
SELECT Course.ID, -- INT
       Student.Name student_name, -- VARCHAR(50)
       StudentProjects.Name project_name, -- VARCHAR(50)
       ProjectLogs.LogDate,
       row_number()over(partition by Course.ID order by ProjectLogs.LogDate desc) rn      -- DATETIME
FROM ProjectLogs INNER JOIN
     Student ON Student.ID = ProjectLogs.ID INNER JOIN
     StudentProjects ON StudentProjects.ID = Student.ID INNER JOIN
     Course ON Course.ID = Student.ID
) q
where rn = 1;

1
投票

您可以使用CTE获取每个学生的最大LogDate,然后将其加入查询的简化版本,如下所示:

;WITH MaxLogDate AS
(
    SELECT StudentID
        ,LogDate = MAX(LogDate) 
    FROM ProjectLogs
    GROUP BY StudentID
)
SELECT c.ID
    ,s.Name
    ,sp.Name
    ,m.LogDate
FROM Courses c
INNER JOIN Student s ON s.ID = c.StudentID
INNER JOIN StudentProjects sp ON sp.StudentID = s.ID
INNER JOIN MaxLogDate m ON m.StudentID = s.ID
© www.soinside.com 2019 - 2024. All rights reserved.