查询在SQL中进行透视

时间:2013-11-19 06:14:52

标签: sql sql-server pivot

我的数据格式如下:

enter image description here

我需要透视它以获取如下数据。 enter image description here

请帮助!!!

4 个答案:

答案 0 :(得分:2)

像这样的东西。在这种情况下,您需要有一个固定的名称列表。

SELECT 
     SUM(CASE WHEN Student='Mike' THEN [English Mark] ELSE 0 END) as [Mike English Mark],
     SUM(CASE WHEN Student='Mike' THEN [Maths Mark] ELSE 0 END) as [Mike Maths Mark],
     SUM(CASE WHEN Student='Fisher' THEN [English Mark] ELSE 0 END) as [Fisher English Mark],
     SUM(CASE WHEN Student='Fisher' THEN [Maths Mark] ELSE 0 END) as [Fisher Maths Mark],
     SUM(CASE WHEN Student='John' THEN [English Mark] ELSE 0 END) as [John English Mark],
     SUM(CASE WHEN Student='John' THEN [Maths Mark] ELSE 0 END) as [John Maths Mark],
     [TestName]


FROM Table1
GROUP BY [Test Name]

答案 1 :(得分:1)

请尝试:

DECLARE @pivv NVARCHAR(MAX),@Query NVARCHAR(MAX)

SELECT @pivv=COALESCE(@pivv+',','')+ QUOTENAME(Student+'_English_Mark')+','+QUOTENAME(Student+'_Maths_Mark') 
FROM YourTable GROUP BY Student

IF ISNULL(@pivv, '')<>''
SET @Query='SELECT*  FROM(
    select English_Mark Marks, Student+''_English_Mark'' Col, Test_Name From YourTable
    union all
    select Maths_Mark Marks, Student+''_Maths_Mark'' Col, Test_Name From YourTable
    )x pivot (sum(Marks) for Col in ('+@pivv+')) as xx'

IF ISNULL(@Query, '')<>''
    EXEC (@Query)

SQL Fiddle Demo

答案 2 :(得分:1)

您可以使用Pivot运算符编写动态SQL查询:

DECLARE @columns NVARCHAR(MAX)
,@columnsEnglish_Mark NVARCHAR(MAX)
,@columnsMath_Mark NVARCHAR(MAX)
,@columnsFNL NVARCHAR(MAX)
,@sql NVARCHAR(MAX);

SET @columns = N'';
--Get column names for entire pivoting
SELECT @columns += N', ' + QUOTENAME(SpreadCol)
FROM (select distinct student as SpreadCol 
from tblstudent
) AS T;  
PRINT @columns;

--Get column names for Pivot1
SET @columnsEnglish_Mark = N'';
SELECT @columnsEnglish_Mark += N', ISNULL(' + QUOTENAME(SpreadCol) + ',0) AS [' + SpreadCol + '_English_Mark]'
FROM (select distinct student as SpreadCol 
from tblstudent
) AS T
;
PRINT @columnsEnglish_Mark;

--Get column names for Pivot2
SET @columnsMath_Mark = N'';
SELECT @columnsMath_Mark += N', ISNULL(' + QUOTENAME(SpreadCol) + ',0) AS [' + SpreadCol + '_Math_Mark]'
FROM (select distinct student as SpreadCol 
from tblstudent
) AS T
; 
PRINT @columnsMath_Mark;

--Get final list of columns:
SET @columnsFNL = N'';
SELECT @columnsFNL += N', [' + SpreadCol + '_English_Mark], [' + SpreadCol + '_Math_Mark] '
FROM (select distinct student as SpreadCol 
from tblstudent
) AS T
order by T.SpreadCol asc; -- change ordering of columns here
PRINT @columnsFNL;

SET @sql = N'
select tblEnglish_Mark.Test_Name , ' + STUFF(@columnsFNL, 1, 2, '') + ' from 
'
+
'
( SELECT Test_Name, ' + STUFF(@columnsEnglish_Mark, 1, 2, '') + ' 
FROM
(select student as SpreadCol , English_Mark, Test_Name
from tblstudent ) as D
PIVOT
(
sum(English_Mark) FOR SpreadCol IN ('
+ STUFF(REPLACE(@columns, ', [', ',['), 1, 1, '')
+ ')
) AS Pivot1 ) tblEnglish_Mark
inner join
'
+
'
( SELECT Test_Name, ' + STUFF(@columnsMath_Mark, 1, 2, '') + ' 
FROM
(select student as SpreadCol , Test_Name,Math_Mark
from tblstudent ) as D
PIVOT
(
MAx(Math_Mark) FOR SpreadCol IN ('
+ STUFF(REPLACE(@columns, ', [', ',['), 1, 1, '')
+ ')
) as Pivot2 ) tblMath_Mark
on tblEnglish_Mark.Test_Name = tblMath_Mark.Test_Name ;
'

;

PRINT @sql;
EXEC sp_executesql @sql;

希望这有帮助!!!

答案 3 :(得分:1)

我得到的解决方案有点棘手,但非常有活力。 您应该先将表格取消,然后将数据放入临时表中,然后获取旋转的列名称,并将结果放入 @cols 变量中。最后,我创建了一个动态sql字符串来转动包含我的数据的临时表,所以即使新学生被添加到表中,他的2列也将在最终结果中生成。

select test,  col + ' '+ Student stu_col ,  value
INTO
#temp
from Marks 
unpivot(value for col in (english, maths)) unpiv
DECLARE @cols AS NVARCHAR(MAX), @query  AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(stu_col) 
            from #temp order by 1
    FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)') 
,1,1,'')
set @query = 'SELECT test, ' + @cols + ' from 
     (
        select test, Value, stu_col
        from #temp
    ) x
    pivot 
    (
        SUM(Value)
        for stu_col in (' + @cols + ')
    ) p '
exec(@query)
DROP TABLE #temp