MySQL创建一个复杂的查询

时间:2012-11-13 14:28:34

标签: php mysql sql pivot

我有三个表,一个用户表,一个test_sessions表和一个课程表。

我需要创建一个包含完整用户列表的报告。在课程表中,某些课程的字段“track”= 1.如果它等于1,我需要在报告中为该课程添加一列。

test_sessions表有一个complete_date字段以及user_id和course_id。

对于报告,我需要这样的事情:

______|Tracked Course 1|Tracked Course 2 |Tracked Course 3
User 1|complete date   |complete date    |complete date
User 2|complete date   |complete date    |complete date
User 3|complete date   |complete date    |complete date

我希望能够编写一个查询来执行此操作,是否可能?

1 个答案:

答案 0 :(得分:2)

这基本上是PIVOT,但是MySQL没有PIVOT所以你需要使用聚合和CASE语句来复制它。如果您知道要获得的课程名称,您可以对其进行硬编码:

select u.userName,
  max(case when c.coursename = 'Course 1' then s.completed_date end) Course1,
  max(case when c.coursename = 'Course 2' then s.completed_date end) Course2,
  max(case when c.coursename = 'Course 3' then s.completed_date end) Course3
from users u
left join test_sessions s
  on u.user_id = s.user_id
left join courses c
  on s.course_id = c.course_id
group by u.username

请参阅SQL Fiddle with Demo

如果您的课程数量不详,那么您可以使用准备好的声明,类似于:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when c.coursename = ''',
      coursename,
      ''' then s.completed_date end) AS ',
      coursename
    )
  ) INTO @sql
FROM courses;

SET @sql = CONCAT('SELECT u.userName, ', @sql, ' 
                  from users u
                  left join test_sessions s
                    on u.user_id = s.user_id
                  left join courses c
                    on s.course_id = c.course_id
                  group by u.username');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

请参阅SQL Fiddle with demo