SQL返回重复的列值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL返回重复的列值相关的知识,希望对你有一定的参考价值。

我想做的事情:只显示唯一的课程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
答案

这就是你要找的东西:

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;
另一答案

您可以使用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

以上是关于SQL返回重复的列值的主要内容,如果未能解决你的问题,请参考以下文章

如果所需的列值重复 [重复],则 SQL 查询以获取顶部记录

R - 如果列值与字符向量中的任何值匹配,则返回它旁边的列 [重复]

MS SQL 2008 设置主键 该列值为啥还能重复

oracle sql查询以获取没有空格的列值

ORACLE:SQL REGEXP_SUBSTR 返回第一个分号和第二个分号之间的列值。在最后半个 clumn 之后还有其他值

PowerShell从csv文件中读取列值[重复]