我正在进行sql选择,我需要获取ID的所有最小记录。我的问题是,虽然我认为我的代码正在运行,但它通常会返回其他列的错误值,显然是因为我没有使用必须支持我的聚合min函数。这是我的代码。
SELECT *
FROM example_students
INNER JOIN
(SELECT id, student, test, subject, MIN(score), semester
FROM example_student_scores
WHERE studentid=94
GROUP BY studentid, test, subject) as scores
ON example_students.id=scores.studentid
这就是我希望我的代码要做的事情。
从exampletable中选择每个不同的测试和主题组合的最低分数,其中学生具有id#94
以下是该示例的两个(经过大量修改的)表格(我在此处和我的代码中更改了所有列名称。
example_students
id name
----+-----------+
94 Bob
1023 Thomas
example_students_scores
id studentId test subject score semester
----+-----------+-----------+-----------+-----------+-----------
0 94 quiz math 46 fall
1 94 quiz math 71 fall
2 94 quiz math 63 winter
3 94 midterm math 94 winter
4 94 midterm science 72 fall
5 94 quiz math 50 spring
6 94 final math 76 spring
7 1023 quiz math 6 spring
8 1023 quiz math 52 winter
9 1023 quiz science 68 fall
..*
,结果应为
results
id studentId test subject score semester
----+-----------+-----------+-----------+-----------+-----------
0 94 quiz math 46 fall
3 94 midterm math 94 winter
4 94 midterm science 72 fall
6 94 final math 76 spring
问题是,我会为学期专栏(以及我在实际工作中的所有其他专栏)得到错误的值。
鉴于这需要很长时间才能得到无处,这里是sql来创建两个示例数据库:
drop table if exists example_students;
drop table if exists example_students_scores;
create table example_students(
id int(10) primary key,
name char(25)
);
create table example_students_scores(
id int(10) not null,
studentId int(10) not null,
test char(20),
subject char(20),
score int(10) not null default '0',
semester char(20),
primary key (id),
index studentid (studentid)
);
insert into example_students values ('94','Bob');
insert into example_students values ('1023','Thomas');
insert into example_students_scores values ('0' ,'94' ,'quiz' ,'math' ,'46' ,'fall');
insert into example_students_scores values ('1' ,'94' ,'quiz' ,'math' ,'71' ,'fall');
insert into example_students_scores values ('2' ,'94' ,'quiz' ,'math' ,'63' ,'winter');
insert into example_students_scores values ('3' ,'94' ,'midterm' ,'math' ,'94' ,'winter');
insert into example_students_scores values ('4' ,'94' ,'midterm' ,'science' ,'72' ,'fall');
insert into example_students_scores values ('5' ,'94' ,'quiz' ,'math' ,'50' ,'spring');
insert into example_students_scores values ('6' ,'94' ,'final' ,'math' ,'76' ,'spring');
insert into example_students_scores values ('7' ,'1023' ,'quiz' ,'math' ,'6' ,'spring');
我会感激任何指示或提示,只是在上线一周后才弄清楚你的工作是错误的,这是非常尴尬的!
答案 0 :(得分:4)
在MySQL中,当您在选择中包含字段而不在组中时,您将获得任意值。在这种情况下,您不能简单地在组中包含学期和测试ID,因为您将无法获得所需的结果。
为了实现这一目标,你必须找到每个学生,考试,科目的最低分数,然后将其重新加入原始表格
SELECT *
FROM example_students_scores ess
INNER JOIN (SELECT studentid,
test,
subject,
Min(score) score
FROM example_students_scores
WHERE studentid = 94
GROUP BY studentid,
test,
subject) scores
ON ess.studentid = scores.studentid
AND ess.test = scores.test
AND ess.subject = scores.subject
AND ess.score = scores.score
另一种不太常规的方法是对不等式进行自反连接。
SELECT
s.*
FROM
example_students_scores s
LEFT JOIN example_students_scores s2
ON s.studentID = s2.studentID
AND s.test = s2.test
AND s.subject = s2.subject
AND s.score > s2.score
WHERE
s.studentid = 94
AND
s2.score is null
如果您对创建平局破坏者感兴趣,只需添加一个或条件
SELECT
s.*
FROM
example_students_scores s
LEFT JOIN example_students_scores s2
ON s.studentID = s2.studentID
AND s.test = s2.test
AND s.subject = s2.subject
AND (s.score > s2.score
or s.id > s2.id ) -- Added for tie breaker
WHERE
s.studentid = 94
AND
s2.score is null
SQL Fiddle Demo注意:我修改了数据以包含平局情况
答案 1 :(得分:2)
这应该适合你:
select ss2.id score_id,
ss2.studentid,
ss1.test,
ss2.subject,
ss1.score,
ss2.semester
from example_students st
left join
(
select min(score) score, test, subject, studentid
from example_students_scores
group by test, studentid, subject
) ss1
on st.id = ss1.studentid
left join example_students_scores ss2
on st.id = ss2.studentid
and ss1.score = ss2.score
and ss1.test = ss2.test
where st.id = 94
order by ss2.id
答案 2 :(得分:1)
试试这个解决方案:
select es.name, e.studentid, e.test, e.subject, e.score as MinScore, e.semester
from example_students_scores e
join (
select studentid, test, subject, min(score) as score
from example_students_scores
group by studentid, test, subject) e2 on e.studentid=e2.studentid
and e.test=e2.test
and e.subject=e2.subject
and e.score=e2.score
join example_students es on e.studentid = es.id
答案 3 :(得分:1)
如果两个example_student_score碰巧具有相同的分数,则需要避免输出中的重复。 Min()会导致重复。
执行任务的一种很好的方法是使用窗口函数和row_number()。
如果窗口功能不可用,则以下方式模拟“第一组”功能可能是:
SELECT *
FROM example_students es
JOIN example_student_scores ss ON ss.studentid= es.id
WHERE es.id = 94
AND NOT EXISTS (
SELECT *
FROM example_student_scores nx
WHERE nx.studentid = ss.studentid
AND nx.test = ss.test
AND nx.subject = ss.subject
AND ( nx.score < ss.score
-- tie breaker
OR ( nx.score == ss.score AND nx.id < ss.id)
)
)
;
答案 4 :(得分:1)
select
*
from
example_students_scores s1
where
studentId = 94 and
score = (select
min(score)
from
example_students_scores s2
where
s2.studentId = s1.studentId and
s2.subject = s1.subject and
s2.test = s1.test
group by
studentId, test, subject
)
答案 5 :(得分:0)
以下查询是否符合您的要求?
SELECT test, subject, MIN(score) as minscore
FROM example_student_scores
WHERE studentid=94
GROUP BY test, subject
答案 6 :(得分:0)
只需选择和分组所需的列:
SELECT *
FROM example_students
INNER JOIN
(SELECT studentid, test, subject, MIN(score), semester
FROM example_student_scores
GROUP BY studentid, test, subject,semester) scores
ON example_students.id=scores.studentid
WHERE studentid=94
在列上使用聚合函数时,SELECT子句中的所有其他属性必须出现在GROUP BY子句中。
查询的其余部分对我来说听起来不错。