我有一个看起来像这样的表:
studentID | subjectID | attendanceStatus | classDate | classTime | lecturerID |
12345678 1234 1 2012-06-05 15:30:00
87654321
12345678 1234 0 2012-06-08 02:30:00
我想要一个查询,报告学生是否缺席3个或更多连续课程。基于studentID和2个特定日期之间的特定主题。每个班级都有不同的时间。该表的架构是:
PK(`studentID`, `classDate`, `classTime`, `subjectID, `lecturerID`)
出勤状态:1 =现在,0 =缺席
编辑:有问题的问题,以便它更准确,真正描述了我的意图。
答案 0 :(得分:1)
我无法为此创建SQL查询。相反,我尝试了一个PHP解决方案:
0
然后我意识到这个逻辑很容易使用MySQL变量来实现,所以:
SET @studentID = 0;
SET @subjectID = 0;
SET @absentRun = 0;
SELECT *,
CASE
WHEN (@studentID = studentID) AND (@subjectID = subjectID) THEN @absentRun := IF(attendanceStatus = 1, 0, @absentRun + 1)
WHEN (@studentID := studentID) AND (@subjectID := subjectID) THEN @absentRun := IF(attendanceStatus = 1, 0, 1)
END AS absentRun
FROM table4
ORDER BY studentID, subjectID, classDate
您可以将此查询嵌套在另一个选择absentRun >= 3
。
答案 1 :(得分:0)
此查询适用于预期结果:
SELECT DISTINCT first_day.studentID
FROM student_visits first_day
LEFT JOIN student_visits second_day
ON first_day.studentID = second_day.studentID
AND DATE(second_day.classDate) - INTERVAL 1 DAY = date(first_day.classDate)
LEFT JOIN student_visits third_day
ON first_day.studentID = third_day.studentID
AND DATE(third_day.classDate) - INTERVAL 2 DAY = date(first_day.classDate)
WHERE first_day.attendanceStatus = 0 AND second_day.attendanceStatus = 0 AND third_day.attendanceStatus = 0
它正在连续3个日期为每个学生加入表'student_visits'(让我们将你的原始表名称)连接到自己,并最终在这些天检查缺席。不同的是确保结果连续3天以上不会包含重复结果。
此查询不考虑特定主题的缺席 - 每个学生连续缺席3天或更长时间。要考虑主题,只需在每个ON子句中添加.subjectID:
ON first_day.subjectID = second_day.subjectID
P.S。:不确定它是最快的方式(至少它不是唯一的方式)。
答案 2 :(得分:0)
不幸的是,mysql不支持Windows功能。使用row_number()或更好的累积总和(在Oracle中支持)会更容易。
我将描述解决方案。想象一下,您的表中还有两列:
关键的观察结果是,这两个值之间的差异对于连续缺席是不变的。因为您使用的是mysql,所以可以考虑将这些列添加到表中。在查询中添加它们是非常具有挑战性的,这就是为什么这个答案很长的原因。
鉴于关键观察,您的问题的答案由以下查询提供:
select studentid, subjectid, absenceid, count(*) as cnt
from (select a.*, (ClassSeqNum - AbsentSeqNum) as absenceid
from Attendance a
) a
group by studentid, subjectid, absenceid
having count(*) > 2
(好的,这给每个学科的学生提供了每一个缺席顺序,但我认为你可以弄清楚如何将这个减少到学生名单。)
如何分配序列号?在mysql中,您需要进行自我加入。因此,以下添加了ClassSeqNum:
select a.StudentId, a.SubjectId, count(*) as ClassSeqNum
from Attendance a join
Attendance a1
on a.studentid = a1.studentid and a.SubjectId = a1.Subjectid and
a.ClassDate >= s1.classDate
group by a.StudentId, a.SubjectId
以下添加缺席序列号:
select a.StudentId, a.SubjectId, count(*) as AbsenceSeqNum
from Attendance a join
Attendance a1
on a.studentid = a1.studentid and a.SubjectId = a1.Subjectid and
a.ClassDate >= a1.classDate
where AttendanceStatus = 0
group by a.StudentId, a.SubjectId
所以最终查询如下:
with cs as (
select a.StudentId, a.SubjectId, count(*) as ClassSeqNum
from Attendance a join
Attendance a1
on a.studentid = a1.studentid and a.SubjectId = a1.Subjectid and
a.ClassDate >= s1.classDate
group by a.StudentId, a.SubjectId
),
a as (
select a.StudentId, a.SubjectId, count(*) as AbsenceSeqNum
from Attendance a join
Attendance a1
on a.studentid = a1.studentid and a.SubjectId = a1.Subjectid and
a.ClassDate >= s1.classDate
where AttendanceStatus = 0
group by a.StudentId, a.SubjectId
)
select studentid, subjectid, absenceid, count(*) as cnt
from (select cs.studentid, cs.subjectid,
(cs.ClassSeqNum - a.AbsentSeqNum) as absenceid
from cs join
a
on cs.studentid = a.studentid and cs.subjectid = as.subjectid
) a
group by studentid, subjectid, absenceid
having count(*) > 2