SQLite AVG() 返回与行相同的结果
Posted
技术标签:
【中文标题】SQLite AVG() 返回与行相同的结果【英文标题】:SQLite AVG() returns same result as row 【发布时间】:2018-12-02 20:35:11 【问题描述】:在使用AVG()
计算学生的平均分时,我注意到我的结果与每行输入的结果相同。
例如:
在上图中,Jeff 的第 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);
谁能指出我的查询中的缺陷?
【问题讨论】:
【参考方案1】:数据有点混乱,因为 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
确实是引用其他表的整数,那么更多的连接以获得您想要的实际字符串名称。
【讨论】:
您还可以指出AVG(DISTINCT)
基本上永远不会是正确的做法。
@GordonLinoff 没错,我错过了那个。以上是关于SQLite AVG() 返回与行相同的结果的主要内容,如果未能解决你的问题,请参考以下文章