我正在用PHP和MySQL建立一个虚拟教室。该教室由课程组成,每个课程包含不同的主题或模块。学生必须检查每个模块,最后,通过摘要(评估板)来了解学生是否通过了课程。
话虽如此,我有一个表,用于存储每个学生的评估,并在其中保存 inscripcion_id (学生-题词ID), modulo_id (模块ID) , fecha (考试日期), aciertos (number_of_right_answers), ultima_convocatoria (评估_last_convocatory)和estado(状态)。
SQL小提琴-> here
通过一些先前建立的规则,告诉我学生是否通过了某个模块,我得到了以下数据集:
+----------------+-----------+---------------------+----------+---------------------+--------+------------+
| inscripcion_id | modulo_id | fecha | aciertos | ultima_convocatoria | estado | ev |
+----------------+-----------+---------------------+----------+---------------------+--------+------------+
| 890 | 1 | 2018-01-24 22:26:09 | 8 | 2 | 1 | aprobado |
| 890 | 2 | 2018-01-24 22:36:58 | 3 | 3 | 0 | suspendido |
| 890 | 5 | 2018-01-24 22:38:50 | 3 | 1 | 0 | suspendido |
| 890 | 6 | 2018-01-24 22:44:20 | 7 | 3 | 0 | suspendido |
| 891 | 1 | 2018-01-25 09:24:42 | 8 | 1 | 1 | aprobado |
| 891 | 2 | 2018-01-25 10:01:55 | 4 | 8 | 0 | suspendido |
| 891 | 4 | 2018-01-25 10:51:49 | 5 | 3 | 1 | suspendido |
| 891 | 5 | 2018-01-25 10:23:45 | 9 | 1 | 1 | aprobado |
| 891 | 6 | 2018-01-25 11:21:20 | 7 | 3 | 0 | suspendido |
| 896 | 1 | 2018-01-25 11:55:48 | 1 | 1 | 1 | suspendido |
| 898 | 1 | 2018-01-25 14:01:51 | 6 | 1 | 1 | suspendido |
| 907 | 1 | 2018-03-25 16:06:18 | 3 | 1 | 0 | suspendido |
| 907 | 2 | 2018-03-25 16:07:34 | 3 | 1 | 0 | suspendido |
| 907 | 3 | 2018-03-25 16:09:04 | 3 | 1 | 0 | suspendido |
| 907 | 4 | 2018-03-25 16:08:13 | 3 | 1 | 0 | suspendido |
| 907 | 5 | 2018-03-25 16:10:37 | 2 | 1 | 0 | suspendido |
| 907 | 6 | 2018-03-25 16:08:44 | 3 | 1 | 0 | suspendido |
+----------------+-----------+---------------------+----------+---------------------+--------+------------+
此数据是通过以下查询获得的:
SELECT e1.inscripcion_id,
e1.modulo_id,
e1.fecha,
e1.aciertos,
e1.convocatoria AS ultima_convocatoria,
e1.estado,
if (
( e1.modulo_id in (SELECT modulo.modulo_id FROM modulo WHERE modulo.curso_id = 1 AND modulo.categoria_id = 1)
AND e1.aciertos <= 7 )
OR ( e1.modulo_id = (SELECT modulo.modulo_id FROM modulo WHERE modulo.curso_id = 1 AND modulo.categoria_id = 2)
AND e1.aciertos <= 11 ),
"suspendido",
"aprobado"
) AS ev
FROM (
SELECT inscripcion_id,
modulo_id,
MAX(convocatoria) AS max_convocatoria
FROM `evaluacion`
GROUP BY inscripcion_id,
modulo_id
ORDER BY `inscripcion_id` ASC,
`modulo_id` ASC,
`convocatoria` ASC
) AS e2
INNER JOIN evaluacion AS e1
ON e1.inscripcion_id = e2.inscripcion_id
AND e1.modulo_id = e2.modulo_id
AND e1.convocatoria = e2.max_convocatoria
如您所见,学生890已经制作了模块1、2、5和6。我要实现的是,这些模块仍在等待处理中,因此我也得到了以前的数据组。例子:
+----------------+-----------+---------------------+----------+---------------------+--------+------------+
| inscripcion_id | modulo_id | fecha | aciertos | ultima_convocatoria | estado | ev |
+----------------+-----------+---------------------+----------+---------------------+--------+------------+
| 890 | 1 | 2018-01-24 22:26:09 | 8 | 2 | 1 | aprobado |
| 890 | 2 | 2018-01-24 22:36:58 | 3 | 3 | 0 | suspendido |
| 890 | 3 | NULL | NULL | NULL | NULL | pendiente |
| 890 | 4 | NULL | NULL | NULL | NULL | pendiente |
| 890 | 5 | 2018-01-24 22:38:50 | 3 | 1 | 0 | suspendido |
| 890 | 6 | 2018-01-24 22:44:20 | 7 | 3 | 0 | suspendido |
| 891 | 1 | 2018-01-25 09:24:42 | 8 | 1 | 1 | aprobado |
| 891 | 2 | 2018-01-25 10:01:55 | 4 | 8 | 0 | suspendido |
| 891 | 3 | NULL | NULL | NULL | NULL | pendiente |
| 891 | 4 | 2018-01-25 10:51:49 | 5 | 3 | 1 | suspendido |
| 891 | 5 | 2018-01-25 10:23:45 | 9 | 1 | 1 | aprobado |
| 891 | 6 | 2018-01-25 11:21:20 | 7 | 3 | 0 | suspendido |
| 896 | 1 | 2018-01-25 11:55:48 | 1 | 1 | 1 | suspendido |
| 896 | 2 | NULL | NULL | NULL | NULL | pendiente |
| 896 | 3 | NULL | NULL | NULL | NULL | pendiente |
| 896 | 4 | NULL | NULL | NULL | NULL | pendiente |
| 896 | 5 | NULL | NULL | NULL | NULL | pendiente |
| 896 | 6 | NULL | NULL | NULL | NULL | pendiente |
| ... | | | | | | |
+----------------+-----------+---------------------+----------+---------------------+--------+------------+
结果是添加了学生尚未完成的模块,并为 ev 列添加了新值“ pending”。
我不知道该怎么做...我尝试过,我搜索了互联网,但什么都没有:(
最终目标是什么?我要获得的所有学生都拥有待修课程(即他们有 some 个待修模块)的最终名单。 / s),向他们发送提醒电子邮件,通知他们必须检查剩余模块的自身。对于已批准或暂停的人,不会向他们发送电子邮件。
你能帮我吗?
SQL小提琴-> here
非常感谢
答案 0 :(得分:1)
假设您希望让评估表中没有模块的学生像示例中提供的那样“待定”。让学生加入所有模块的方法是对modulo
和evaluacion
进行完全加入,以获得完整的inscripcion_id
modulo_id
的完整集合。然后与现有查询左联接将提供您想要的结果。
SELECT fs.inscripcion_id,
fs.modulo_id,
e3.fecha,
e3.aciertos,
e3.ultima_convocatoria,
e3.estado,
IF(e3.ev IS NULL, "pendiente", e3.ev) AS ev
FROM (SELECT m.modulo_id,
e.inscripcion_id
FROM modulo m,
evaluacion e
GROUP BY m.modulo_id,
e.inscripcion_id) AS fs
LEFT JOIN (SELECT
e1.inscripcion_id,
e1.modulo_id,
e1.fecha,
e1.aciertos,
e1.convocatoria
AS
ultima_convocatoria
,
e1.estado,
IF (( e1.modulo_id IN (SELECT modulo.modulo_id
FROM modulo
WHERE modulo.curso_id = 1
AND modulo.categoria_id =
1)
AND e1.aciertos <= 7 )
OR ( e1.modulo_id = (SELECT modulo.modulo_id
FROM modulo
WHERE
modulo.curso_id = 1
AND modulo.categoria_id = 2)
AND e1.aciertos <= 11 ), "suspendido",
"aprobado")
AS ev
FROM (SELECT inscripcion_id,
modulo_id,
Max(convocatoria) AS max_convocatoria
FROM `evaluacion`
GROUP BY inscripcion_id,
modulo_id
ORDER BY `inscripcion_id` ASC,
`modulo_id` ASC,
`convocatoria` ASC) AS e2
INNER JOIN evaluacion AS e1
ON e1.inscripcion_id = e2.inscripcion_id
AND e1.modulo_id = e2.modulo_id
AND e1.convocatoria = e2.max_convocatoria)
AS e3
ON fs.modulo_id = e3.modulo_id
AND fs.inscripcion_id = e3.inscripcion_id
ORDER BY fs.inscripcion_id,
fs.modulo_id;
对于进一步的问题, 您可能要使用
SELECT inscripcion_id,
SUM(case when ev = 'aprobado' then 1 else 0 end) as approved_cnt,
SUM(case when ev = 'suspendido' then 1 else 0 end) as suspended_cnt,
SUM(case when ev = 'pendiente' then 1 else 0 end) as pending_cnt
From --the above query...
Group by inscripcion_id
获取每个学生的状态计数,然后使用这些计数进行逻辑计算。
答案 1 :(得分:0)
查看新的sqlfiddle之后 我在下面编写了查询,我认为它应该可以满足您的需求
请注意,每个模块评估不只一次,这意味着每个模块将获得不止一种状态
要解决此问题,您可以添加一个group语句(现在在评论中) 或者您根据自己的需求进行了不同的评估...
SELECT
i.inscripcion_id,
c.curso_id,
c.titulo AS curso_titulo,
m.modulo_id,
m.titulo AS modulo_titulo,
IFNULL(ev.estado,0) AS estado,
m.*
FROM
inscripcion i
INNER JOIN curso c ON c.curso_id = i.curso_id
INNER JOIN modulo m ON m.curso_id = c.curso_id
LEFT JOIN evaluacion ev ON ev.modulo_id = m.modulo_id
WHERE
(ev.estado = 0 OR ev.estado IS NULL)
/*
GROUP BY
m.modulo_id
*/
;