使用数据透视表查询的动态列

时间:2012-02-16 02:11:12

标签: php mysql

我有这个出勤表

---------------------------------------------------------------------------
attendance_id | stud_id      | week       | sy        |sem         |present
---------------------------------------------------------------------------
1             | 1            | 02/18/2012 | 2010-2011 |1st semester|1
2             | 2            | 02/18/2012 | 2010-2011 |1st semester|1
3             | 3            | 02/18/2012 | 2010-2011 |1st semester|1
4             | 1            | 02/25/2012 | 2010-2011 |1st semester|1
5             | 2            | 02/25/2012 | 2010-2011 |1st semester|1
6             | 1            | 03/03/2012 | 2010-2011 |1st semester|1
7             | 2            | 03/03/2012 | 2010-2011 |1st semester|1
8             | 3            | 03/03/2012 | 2010-2011 |1st semester|1

我的查询是

Select cadet_record.fname,cadet_record.lname,cadet_record.mname, student_id,

MAX(case WHEN week = '02/18/2012' then present end) as 'week1',
MAX(case WHEN week = '02/25/2012' then present end) as 'week2'
From attendance
LEFT JOIN cadet_record ON cadet_record.stud_no = attendance.student_id WHERE section = '$section' AND schoolyear = '$year' AND component = '$component' AND semester = '$semester'
GROUP BY student_id

如何在不插入日期的情况下动态调用一周 例如02/28 / 2012,02 / 29/2012等等。 有任何想法吗? =(

2 个答案:

答案 0 :(得分:0)

据我所知,您无法动态地将列添加到SELECT语句中。您要求的是一种呈现数据的方式,这不是MySQL所关心的。你应该在前端处理它。

但是,您可以通过在模型中创建查询并动态添加这些新列来作弊,方法是在查询字符串中动态插入更多MAX(case...。不过,这不是一个好的解决方案。

修改

  

我使用php,我该怎么做?

所以,我想你在谈论丑陋的解决方案。好吧,基本上你应该动态创建你的查询字符串(伪代码):

$initialDay = 02/28/2012;
$lastDay = 03/28/2012;
$dayNumber = 1;
$sql = 'Select cadet_record.fname,cadet_record.lname,cadet_record.mname, student_id';
while ($initialDay <= $lastDay) {
    $sql .= ', MAX(case WHEN week = $initialDay then present end) as day' . $dayNumber;
    $initialDay = $initialDay + 1 day;
    $dayNumber++;
}
$sql .= ' From attendance blah blah...';

然后,对于2012年2月18日至2012年1月18日的日期,您的查询应如下所示:

Select cadet_record.fname,cadet_record.lname,cadet_record.mname, student_id,
,MAX(case WHEN week = '02/18/2012' then present end) as day1
,MAX(case WHEN week = '02/19/2012' then present end) as day2
From attendance
LEFT JOIN cadet_record ON cadet_record.stud_no = attendance.student_id WHERE section = '$section' AND schoolyear = '$year' AND component = '$component' AND semester = '$semester'

GROUP BY student_id

注意我添加了几天而不是几周,因为您的示例显示了增加的天数,尽管列名是周

答案 1 :(得分:0)

如果不旋转表格,您可以通过此查询获得每位学生的每周出勤率:

SELECT 
    cadet_record.fname,
    cadet_record.lname,
    cadet_record.mname, 
    student_id,
    week,
    SUM(present) AS att
FROM attendance
LEFT JOIN cadet_record 
    ON cadet_record.stud_no = attendance.student_id 
WHERE section = '$section' 
    AND schoolyear = '$year' 
    AND component = '$component' 
    AND semester = '$semester'
GROUP BY week, student_id
ORDER BY week, cadet_record.fname, student_id

编辑抱歉,您应该使用SUM,而不是COUNT