使用AVG()
来计算学生的平均分数时,我注意到我的结果与每行的输入相同。
例如:
在上图中,杰夫的第2和第3项分别为83
和85
,但他的avg_mark
并不是一行83.5
我的查询如下:
Select m.stdName, m.markPercent, m.crsName, m.term, AVG(distinct markPercent) as avg_mark
from Marks as m
inner join StudentSchedule as ss on ss.crsName = m.crsName and ss.stdName = m.stdName
Inner JOIn Course as c on c.crsName = m.crsName
where m.stdName like 'Jeff'
group by m.stdName, m.markPercent, m.crsName, m.term;
我的架构中的一些表:
create table Course (
crsID INTEGER PRIMARY KEY AUTOINCREMENT,
crsName VARCHAR(8) NOT NULL,
crsTerm INT NOT NULL
);
CREATE TABLE StudentSchedule(
stdSchedule INTEGER PRIMARY KEY AUTOINCREMENT,
stdName INT NOT NULL,
teacherName INT not NULL,
crsName INT not NULL,
startTime NUMERIC NOT NULL,
endTime NUMERIC NOT NULL,
term INT NOT NULL,
FOREIGN KEY(stdName) references Student(stdID),
FOREIGN KEY(teacherName) REFERENCES Teacher(teacherID),
FOREIGN KEY(crsName) REFERENCES Course(crsID)
);
CREATE TABLE Marks (
markID INTEGER PRIMARY KEY AUTOINCREMENT,
markPercent REAL NOT NULL,
stdName INT NOT NULL,
crsName INT not NULL,
term INT NOT NULL,
FOREIGN KEY(stdName) references Student(stdID),
FOREIGN KEY(crsName) REFERENCES Course(crsID),
FOREIGN KEY(term) references StudentSchedule(term)
);
insert into Course (crsName, crsTerm) values ('COMP4900', 2);
insert into StudentSchedule(stdName, teacherName, crsName, startTime, endTime, term) values ('Jeff','tej','COMP4900',1000,1200,2);
insert into StudentSchedule(stdName, teacherName, crsName, startTime, endTime, term) values ('Jeff','farnaz','COMP4900',1200,200,3);
insert into Marks (markPercent, stdName, crsName, term) values (83.0, 'Jeff','COMP4900', 2);
insert into Marks (markPercent, stdName, crsName, term) values (87.0, 'Jeff','COMP4900', 3);
有人可以指出我的查询中存在缺陷吗?
答案 0 :(得分:2)
数据有点混乱,因为stdName
和crsName
是整数,但是您的INSERT却在其中放入了字符串(不幸的是,SQLite可以让您摆脱困境)。
此外,主要的问题是您正在按m.markPercent
和其他几项进行分组,因此最终一次将聚合函数应用于一行。还有一个奇怪的AVG(distinct markPercent)
并没有多大意义,GROUP BY问题掩盖了这个问题。
最好在派生表中建立平均值并加入平均值。您所追求的平均值可以通过以下方式计算:
select stdName, avg(markPercent) avgMark
from Marks
group by stdName, crsName
您追求的是每门课程学生的平均成绩,这恰恰说明了这一点。将该表用作派生表并连接到表:
select m.stdName, m.markPercent, m.crsName, m.term, a.avgMark
from Marks m
join (select stdName, avg(markPercent) avgMark from Marks group by stdName, crsName) a on m.stdName = a.stdName
where ...
然后,如果stdName
和crsName
确实是引用其他表的整数,则可以进行更多的联接以获得所需的实际字符串名称。