SQL查询获得最高分和最新日期的组合

时间:2014-08-19 14:41:55

标签: sql

我有一个SQL查询,用于查询包含测试分数的表

该表格设置如下ID(主键),UsernameUserIDTest_nameDate_Taken,{{ 1}},Time_TakenNum_questionsGradeTime_Per_questionand

我有以下SQL查询,它为我提供了特定用户的每个测试名称的最高分数:

Test_Slug

我遇到的问题是,如果用户在同一个测试中有多个SELECT t.ID, t.test_Name, t.UserID, t.Test_Slug, t.Grade, t.date_taken FROM academytestsite.testscores t JOIN (SELECT hs.test_Name, hs.UserID, hs.test_Slug, Max(hs.Grade) AS MaxGrade FROM academytestsite.testscores hs GROUP BY hs.test_Name, hs.UserID) mhs ON mhs.test_Name = t.test_Name AND mhs.UserID = t.UserID AND mhs.MaxGrade = t.Grade WHERE t.UserID = 5608 ORDER BY test_name 相同。

我希望查询只提供最新的Grades,而语句会给出所有相同的结果。希望这是有道理的

我尝试按Grade进行分组,但这会在表格中给出每个测试的第一个结果,而不是最新的结果。

4 个答案:

答案 0 :(得分:3)

大多数SQL方言,包括MySQL,缺乏任何直接说法的方式"给我一个特定列的每个值的最佳行"。发布的其他答案都为您提供了一种说法"为特定列的每个值给我一行,其他列等于最佳值。"你也可以说"给我每行没有更好的行,"这就是我在下面所做的。

这方法的技巧是使用LEFT JOIN来查找更好的行,然后使用WHERE子句仅选择行更好的行' ID为NULL。

SELECT t.ID, 
       t.test_Name, 
       t.UserID, 
       t.Test_Slug, 
       t.Grade, 
       t.date_taken 
FROM   academytestsite.testscores t
LEFT JOIN academytestsite.testscores better_row
       ON better_row.test_Name = t.test_Name
      AND better_row.UserID = t.UserID
      AND (better_row.Grade > t.Grade
           OR (better_row.Grade = t.Grade AND better_row.date_taken > t.date_taken))
WHERE better_row.ID IS NULL

当两个等级匹配时,此版本会找到评分最高的每个测试分数,并使用date_taken列作为决胜局。您可以更改" best"的标准。通过更改连接条件来排。例如,如果您只想要每个测试的最新成绩,则可以使用

      AND better_row.date_taken > t.date_taken

如果使用此方法获得多个结果,则需要调整连接条件,以便每个(test_Name,UserID)对只能选择一行作为"最佳& #34;一。如果你有重复的成绩和日期,可以通过使主键成为平局破坏者来实现这一点:

       AND (better_row.Grade > t.Grade
           OR (better_row.Grade = t.Grade AND better_row.date_taken > t.date_taken)
           OR (better_row.Grade = t.Grade AND better_row.date_taken = t.date_taken 
               AND better_row.ID > t.Id))

答案 1 :(得分:0)

试试这个:

SELECT *
FROM academytestsite.testscores t 
INNER JOIN (
   SELECT 
      UserID, 
      test_Name, 
      MAX(date_taken) as date_taken
   FROM academytestsite.testscores
   GROUP BY UserID, test_Name
) mhs ON (mhs.UserID = t.UserID) 
     AND (mhs.test_Name = t.test_Name) 
     AND (mhs.date_taken = t.date_taken)
ORDER BY t.test_Name

请参阅SQL demo

答案 2 :(得分:0)

这也应该有效:

select grade, username, date_taken, time_taken from(
select grade, username, date_taken, time_taken from test_scores a
where a.grade = (select max(grade) from test_scores b where b.username = a.username group by username)
order by date_taken desc, time_taken desc) temp
group by username;

http://sqlfiddle.com/#!2/550d7b/3

答案 3 :(得分:0)

要获得每位用户和考试的最高分,您可以使用自我左联接

select t1.* from testscores t1
left join testscores t2 on
t1.Username = t2.Username
and 
t1.test_name = t2.test_name
and t1.grade < t2.grade 
where t2.id is null
ORDER  BY t1.test_name 

要获得重复相同等级的最新拍摄日期,MAX子查询将非常有用

select t1.* from testscores t1
left join testscores t2 on
t1.Username = t2.Username
and 
t1.test_name = t2.test_name
and t1.grade < t2.grade 
where t2.id is null
and t1.Date_Taken = 
    (select max(t3.Date_Taken) 
     from testscores t3 
     where t3.Username = t1.Username 
     and t3.test_name = t1.test_name 
     and t3.grade = t1.grade
     group by t3.Username , t3.test_name
     )
ORDER  BY t1.test_name 

出于性能原因,如果用户,测试和评分很重要,您可能还会看到distinct结果:

select distinct t1.Username , t1.test_name , t1.Grade from testscores t1
left join testscores t2 on
t1.Username = t2.Username
and 
t1.test_name = t2.test_name
and t1.grade < t2.grade 
where t2.id is null
ORDER  BY t1.test_name 

<强> Fiddle Demo