对于日期间隔,我想显示学生记录的每个工作日的出勤率,记录在三个表[出勤率,学生,人物]中。 表的模式(相关字段):
Attendance Table --------------------- Attendance_Identifier Student_Identifier Classroom_Identifier Attendance_Datetime Attendance_Value ...
Student
------------------
Student_Identifier
Person_Identifier
Classroom_Identifier
...
Person
-----------------
Person_Identifier
Frist_Name
Last_Name
Gender
...
预期报告输出:
Gender Student Mon Tue Wed Thu Fri WeeklyTotal ------------------------------------------------------------------------ Male Ab Stain 2/10 3/12 1/9 1/10 0/10 7/51 Male Pre Senter 10/10 12/12 9/9 9/10 10/10 50/51 ... Female Al Ways 10/10 12/12 9/9 10/10 10/10 51/51 Female Not Often 5/10 5/12 4/9 4/10 5/10 23/51 ...
我还有一个函数可以从日期间隔得到特定日期的计数,比如说日期间隔@s,@ e的总周一,只需:select get_weekday(@s,@e,0).
所以我的存储过程查询是:
set @s = '2016-01-01';
set @e = '2016-12-07';
SELECT
concat(p.Frist_Name, ' ',p.Last_Name) as Student, p.Gender
,GROUP_CONCAT(CASE WHEN DATE_FORMAT(Attendance_Datetime, '%a') = 'Mon'
THEN CONCAT(COUNT(Attendance_Value),'/',get_weekday(@s,@e,0)) ELSE NULL END) AS Mon
,GROUP_CONCAT(CASE WHEN DATE_FORMAT(Attendance_Datetime, '%a') = 'Tue'
THEN CONCAT(COUNT(Attendance_Value),'/',get_weekday(@s,@e,1)) ELSE NULL END) AS Tue
,GROUP_CONCAT(CASE WHEN DATE_FORMAT(Attendance_Datetime, '%a') = 'Wed'
THEN CONCAT(COUNT(Attendance_Value),'/',get_weekday(@s,@e,2)) ELSE NULL END) AS Wed
,GROUP_CONCAT(CASE WHEN DATE_FORMAT(Attendance_Datetime, '%a') = 'Thu'
THEN CONCAT(COUNT(Attendance_Value),'/',get_weekday(@s,@e,3)) ELSE NULL END) AS Thu
,GROUP_CONCAT(CASE WHEN DATE_FORMAT(Attendance_Datetime, '%a') = 'Fri'
THEN CONCAT(COUNT(Attendance_Value),'/',get_weekday(@s,@e,4)) ELSE NULL END) AS Fri
, SUM(COUNT(Attendance_Value)) as WeeklyTotal
FROM Attendance a JOIN Student s ON s.Student_Identifier=a.Student_Identifier
JOIN Person p ON p.Person_Identifier=s.Person_Identifier
WHERE date(Attendance_Datetime) BETWEEN @s AND @e AND a.Classroom_Identifier = '363'
AND (Attendance_Value = 'Present' OR Attendance_Value = 'Late') AND (p.Gender = 'Male' OR p.Gender = 'Female')
AND DATE_FORMAT(Attendance_Datetime, '%a') !='Sat' AND DATE_FORMAT(Attendance_Datetime, '%a')!='Sun'
GROUP BY p.Gender, Student, WeeklyTotal ORDER BY p.Gender, Student;
即使对代码进行了许多调整,每次都会出现以下组函数错误。
Error Code: 1111. Invalid use of group function
基于@Solarflare的第一个建议(我不知道如何尝试第二个建议),我将查询改进为:
SELECT
concat(p.Frist_Name, ' ',p.Last_Name) as Student, p.Gender
,CONCAT(CASE WHEN DATE_FORMAT(Attendance_Datetime, '%a') = 'Mon'
THEN COUNT(Attendance_Value) ELSE 0 END,'/',get_weekday(@s,@e,0) ) AS Mon
,CONCAT(CASE WHEN DATE_FORMAT(Attendance_Datetime, '%a') = 'Tue'
THEN COUNT(Attendance_Value) ELSE 0 END,'/',get_weekday(@s,@e,1) ) AS Tue
,CONCAT(CASE WHEN DATE_FORMAT(Attendance_Datetime, '%a') = 'Wed'
THEN COUNT(Attendance_Value) ELSE 0 END,'/',get_weekday(@s,@e,2) ) AS Wed
,CONCAT(CASE WHEN DATE_FORMAT(Attendance_Datetime, '%a') = 'Thu'
THEN COUNT(Attendance_Value) ELSE 0 END,'/',get_weekday(@s,@e,3) ) AS Thu
,CONCAT(CASE WHEN DATE_FORMAT(Attendance_Datetime, '%a') = 'Fri'
THEN COUNT(Attendance_Value) ELSE 0 END,'/',get_weekday(@s,@e,4) ) AS Fri
, COUNT(Attendance_Value) as WeeklyTotal
FROM Attendance a JOIN Student s ON s.Student_Identifier=a.Student_Identifier
JOIN Person p ON p.Person_Identifier=s.Person_Identifier
WHERE date(Attendance_Datetime) BETWEEN @s AND @e AND a.Classroom_Identifier = '363'
AND (Attendance_Value = 'Present' OR Attendance_Value = 'Late') AND (p.Gender = 'Male' OR p.Gender = 'Female')
AND DATE_FORMAT(Attendance_Datetime, '%a') !='Sat' AND DATE_FORMAT(Attendance_Datetime, '%a')!='Sun'
GROUP BY Student,Gender,DATE_FORMAT(Attendance_Datetime, '%a') ORDER BY p.Gender, Student,Mon DESC;
,结果如下:
答案 0 :(得分:1)
只有一些小的东西可以让它发挥作用,试试这个:
SELECT
concat(p.Frist_Name, ' ',p.Last_Name) as Student, p.Gender
,concat(cast(COUNT(CASE WHEN weekday(Attendance_Datetime) = 0
then 1 END) as char), '/', get_weekday(@s,@e,0)) as Mon
,concat(cast(COUNT(CASE WHEN weekday(Attendance_Datetime) = 1
then 1 END) as char), '/', get_weekday(@s,@e,1)) as Tue
,concat(cast(COUNT(CASE WHEN weekday(Attendance_Datetime) = 2
then 1 END) as char), '/', get_weekday(@s,@e,2)) as Wed
,concat(cast(COUNT(CASE WHEN weekday(Attendance_Datetime) = 3
then 1 END) as char), '/', get_weekday(@s,@e,3)) as Thu
,concat(cast(COUNT(CASE WHEN weekday(Attendance_Datetime) = 4
then 1 END) as char), '/', get_weekday(@s,@e,4)) as Fri
,COUNT(Attendance_Value) as WeeklyTotal
FROM Attendance a
JOIN Student s ON s.Student_Identifier=a.Student_Identifier
JOIN Person p ON p.Person_Identifier=s.Person_Identifier
WHERE date(Attendance_Datetime) BETWEEN @s AND @e
AND a.Classroom_Identifier = '363'
AND (Attendance_Value = 'Present' OR Attendance_Value = 'Late')
AND (p.Gender = 'Male' OR p.Gender = 'Female')
AND weekday(Attendance_Datetime) not in (5,6)
GROUP BY Student, Gender ORDER BY p.Gender, Student, Mon DESC;
透视图使用case
完成,它会在日期具有正确的工作日时计算。否则,该值为null
(不是0
),只有它没有计数(else null
未被写入)。