我有一系列的表,我想从中以下列格式返回行:
Student ID | Last Name | First Name | Quiz Scores
-------------------------------------------------
xxxxxxx | Snow | Jon | 0,0,0,0,0,0,0,0
有 3 个相关表(不能更改任何现有的数据库结构):
person
- 组织中所有人的表格enrollment
- 学生和教师注册数据表tilt.quiz
- 测验分数表,每行存储一个单独的分数
其中棘手的部分是测验分数。仅当学生参加了测验时,测验分数的一行才会存在。每个 quiz
行都有一个 module
,1 - 8。所以一个学生可能的测验数据可能是(每个都是单独的一行):
person_id | module | score
---------------------------
223355 | 1 | 100
223355 | 2 | 95
223355 | 4 | 80
223355 | 7 | 100
我需要以 8 个逗号分隔值按正确顺序返回测验分数,无论是否缺少任何或所有测验。
我目前有以下查询:
SELECT
person.id,
first_name,
last_name,
GROUP_CONCAT(tilt.quiz.score) AS scores
FROM person
LEFT JOIN enrollment ON person.id = enrollment.person_id
LEFT JOIN tilt.quiz ON person.id = tilt.quiz.person_id
WHERE
enrollment.course_id = '$num' AND enrollment_status_id = 1
GROUP BY person.id
ORDER BY last_name
问题是:
- 它不按模块排序测验
- 如果缺少任何测验,它只会返回较少的值
所以我需要 GROUP_CONCAT
分数至少包含用于缺少测验值的逗号,并正确排序。
我考虑过的一个解决方案是创建一个临时的测验分数表,但我不确定这是最有效的方法,也不确定该怎么做。
编辑:另一种解决方案是执行查询以单独检查每个测验的存在,但这看起来很笨拙(总共 9 个查询而不是 1 个);我希望有更优雅的方式。
这将如何实现?
最佳答案
这里有一些关于您的数据结构的假设,但这应该非常接近您所追求的。查看 GROUP_CONCAT
的文档和 COALESCE
.
SELECT `person`.`id`, `person`.`first_name`, `person`.`last_name`,
GROUP_CONCAT(
COALESCE(`tilt`.`quiz`.`score`, 'N/A')
ORDER BY `tilt`.`quiz`.`module_id`
) AS `scores`
FROM `person`
CROSS JOIN `modules`
LEFT JOIN `enrollment` USING (`person_id`)
LEFT JOIN `tilt`.`quiz` USING (`person_id`, `module_id`)
WHERE (`enrollment`.`course_id` = '$num')
AND (`enrollment`.`enrollment_status_id` = 1)
GROUP BY `person`.`id`
ORDER BY `person`.`last_name`
关于php - 具有排序和缺失字段的 GROUP_CONCAT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28487792/