带动态列的SQL查询(PIVOT)

时间:2012-12-30 04:11:17

标签: mysql sql pivot

我正在尝试编写一个将转换此表的SQL查询:

Start_time    End_time   Instructor    Student  
9:00          9:35       Joe Bob       Andrew
9:00          9:35       Joe Bob       Smith
9:00          9:35       Roberto       Andy
10:00         10:35      Joe Bob       Angelica
11:00         11:20      Roberto       Bob

这样的事情:

Instructor    9:00              10:00         11:00
Joe Bob       Andrew, Smith     Angelica      NULL
Roberto       Andy              NULL          Bob

我认为这是某种PIVOT命令,但我不确定如何编写SQL查询。时间都是动态生成的,所以如果查询会动态生成第二个表中的列名,我会更喜欢它(例如,如果原始表包含11:30的额外开始时间,那么应该有一个新列为11 :结果中的30个。

提前谢谢你,我已经玩了一段时间,但却无法自己动手。我可以提供SQL INSERT命令,以便在必要时为您提供完整的数据。

编辑:将此select语句的结果作为VIEW特别有用。谢谢!

编辑2: 生成第一个表的视图的代码是:

CREATE VIEW schedule_view AS SELECT RTRIM(SUBSTRING(students.schedule_first_choice, 1, 5)) AS start_time, RTRIM(SUBSTRING(students.schedule_first_choice, -10, 5) AS end_time, CONCAT(instructors.first_name, ' ', instructors.last_name) AS instructor_name, 
    CONCAT(students.first_name, ' ', students.last_name) AS student_name , students.swim_america_level as class 
    FROM students, instructors WHERE students.instructor_id = instructors.instructor_id AND students.season = 
    (SELECT constant_value FROM constants WHERE constant_name = 'season') AND students.year = 
    (SELECT constant_value FROM constants WHERE constant_name = 'year')

2 个答案:

答案 0 :(得分:2)

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'GROUP_CONCAT(case when Start_time = ''',
      Start_time,
      ''' then Student ELSE NULL end) AS ',
      CONCAT('`',Start_time,'`')
    )
  ) INTO @sql
FROM Table1;

SET @sql = CONCAT('SELECT Instructor, ', @sql, ' 
                   FROM Table1 
                   GROUP BY Instructor');

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

答案 1 :(得分:-1)

这些在SQL SEREVR中执行和测试的所有查询

在PIVOT中使用静态栏目

 Select * from  
 (
      select Instructor,Start_time, STUFF((select ',' + student from Table1 a where         
      a.Start_time = b.Start_time and
      a.Instructor=b.Instructor for xml     path('')),1,1,'') as student
      from table1 b ) x 
 PIVOT 
 (
      max(Student) 
      for start_time IN ([9:00],[10:00], [11:00])
 ) p

使用临时表

动态创建PIVOT TABLE
 Declare @tab nvarchar(max) 
 Declare @pivottab nvarchar(max)

 Create table #Table2 (     
        instructor varchar(100),    
        student    varchar(100),    
        start_time varchar(10) 
 ); 

 insert into #Table2 (instructor,student,start_time) 
 select 
       Instructor,  
       STUFF((Select ','+student 
             from Table1 as a
         Where 
             a.Start_time = b.Start_time and 
                 a.Instructor=b.Instructor
             for xml path('')),1,1,''),
       Start_time  
 from table1 as b

 select @tab = coalesce(@tab + ',['+start_time+']' ,'['+start_time+']')  
 from #Table2  
 group by Start_time

 set @pivottab = 
     N' select * from  (
                        select Instructor, Start_time, student from #Table2 
                       ) x 
        PIVOT (
              max(Student) for start_time IN ('+@tab+') 
        ) p'

 execute(@pivottab)

 if exists(select * from #table2)
 Begin
Drop table #table2 
 End

动态创建PIVOT TABLE

Declare @tab nvarchar(max)
Declare @pivottab nvarchar(max)

Select @tab = coalesce(@tab + ',['+start_time+']' , '['+start_time+']') from Table1
group by Start_time

set @pivottab = N'
select *
from 
(
  select Instructor,Start_time,STUFF((select '+ char(39)+char(44)+char(39) + '+ a.student from Table1 as a
where a.Start_time = b.Start_time and a.Instructor=b.Instructor for xml path('''')),1,1,'''') 
as Student from table1 as b

) x
PIVOT
(
  max(Student)
  for start_time IN ('+@tab+')
) p'

execute(@pivottab)