我有一个SQL查询,用于查询包含测试分数的表
该表格设置如下ID
(主键),Username
,UserID
,Test_name
,Date_Taken
,{{ 1}},Time_Taken
,Num_questions
,Grade
,Time_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
进行分组,但这会在表格中给出每个测试的第一个结果,而不是最新的结果。
答案 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;
答案 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 强>