2012-11-13 65 views
1

我有三个表,一个用户表,test_sessions表和一个课程表。MySQL创建一个复杂的查询

我需要创建一个包含用户完整列表的报表。在课程表中,有些课程的“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 

我希望能够编写一个查询要做到这一点,这可能吗?

+0

,你能否告诉我们,在他们的一些测试值的三个表的设计? – Blueboye

回答

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