SQLite AVG()返回与行相同的结果

时间:2018-06-23 17:42:12

标签: sql sqlite average aggregate-functions

使用AVG()来计算学生的平均分数时,我注意到我的结果与每行的输入相同。

例如:

AVG() result

在上图中,杰夫的第2和第3项分别为8385,但他的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 个答案:

答案 0 :(得分:2)

数据有点混乱,因为stdNamecrsName是整数,但是您的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 ...

然后,如果stdNamecrsName确实是引用其他表的整数,则可以进行更多的联接以获得所需的实际字符串名称。