我有一个问题:
select score, count(1) as 'NumStudents' from testresults where testid = 'mytestid' group by score order by score
其中testresults表包含测试中学生的表现。假设测试的最大标记为10,样本结果如下所示。
得分,NumStudents
0 10
1 20
2 12
3 5
5 34
..×10 23
正如您所看到的,此查询不会返回任何学生没有得分的记录。例如。没有人在测试中得分为4/10,并且在查询输出中没有得分= 4的记录。
我想更改查询,以便我可以使用0作为NumStudents字段的值来获取这些丢失的记录。这样我的最终输出就会有最多+1个记录,每个记录对应一个记录。
有什么想法吗?
修改
数据库包含多个测试,测试的最大标记是测试定义的一部分。因此,拥有一个用于存储所有可能分数的新表是不可行的。从某种意义上说,每当我使用新的最大标记创建新测试时,我都需要确保更新新表以包含这些分数。
答案 0 :(得分:2)
SQL擅长处理数据库中的数据集,但对数据库中不的数据集不太好。
最佳解决方法是为您需要的值保留一个小表:
CREATE TABLE ScoreValues (score int);
INSERT INTO ScoreValues (score)
VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
鉴于您在另一个表中定义测试的最大标记的评论,您可以通过以下方式加入该表,只要ScoreValues
确定值至少高于或高于最大考试的最大分数:
SELECT v.score, COUNT(tr.score) AS 'NumStudents'
FROM ScoreValues v
JOIN Tests t ON (v.score <= t.maxmarks)
LEFT OUTER JOIN TestResults tr ON (v.score = tr.score AND t.testid = tr.testid)
WHERE t.testid = 'mytestid'
GROUP BY v.score;
答案 1 :(得分:1)
最明显的方法是创建一个名为“Scores”的表,然后将表外部连接到表中。
SELECT s.score,COUNT(1)AS scoreCount
从得分AS s
LEFT OUTER JOIN testScores AS ts
ON s.score = ts.score
GROUP BY s.score
如果您不想创建表格,可以使用
选择
1作为分数,SUM(CASE WHEN ts.score = 1 THEN 1 ELSE 0 END)AS scoreCount,
2作为分数,SUM(CASE WHEN ts.score = 2 THEN 1 ELSE 0 END)AS scoreCount,
3作为分数,SUM(当ts.score = 3然后1 ELSE 0 END时的情况)AS scoreCount,
4作为分数,SUM(CASE WHEN ts.score = 4 THEN 1 ELSE 0 END)AS scoreCount,
...
10作为分数,SUM(当ts.score = 10然后1 ELSE 0 END时)作为scoreCount
来自testScores AS ts
答案 2 :(得分:0)
MySQL是否支持设置返回功能? PostgreSQL的最新版本有一个函数generate_series(start, stop)
,第一行产生值start
,第二行产生start+1
,依此类推stop
stop
第1行。这样做的好处是你可以将这个函数放在FROM
子句中的子选择中,然后加入它,而不是像le dorfier和Bill Karwin所建议的那样创建和填充表并加入它。
答案 3 :(得分:0)
就像一次心理练习一样,我想出了这个,以便在MySQL中生成一个序列。只要方块上的所有数据库中的表的数量小于序列的总长度,它就会起作用。我不会推荐它用于生产;)
SELECT @n:=@n+1 as n from (select @n:=-1) x, Information_Schema.Tables y, Information_Schema.Tables WHERE @n<20; /* sequence from 0 to 20 inclusive */