[英]Convert Rows to Column In SQL Server 2008
我想使用Pivot
将行转换为列。
我有三个表:
StudentID
和StudentName
Student
表 Subject
表中包含SubjectID
和SubjectName
列 Student Subject
的列表StudentSubjectID
, StudentID
, SubjectID
和Date
现在,我编写了一个查询以从上述表中获取数据
StudentID StudentName SubjectID SubjectName DateTime
-----------------------------------------------------------
1 Yasser 1 Math 1/1/2017
1 Yasser 1 English 1/1/2017
1 Yasser 1 Math 3/1/2017
1 Mark 1 Math 1/1/2017
1 John 1 Math 6/1/2017
现在,我将制作一个月度报告以显示每月的“学生主题”,输出应为
Student/Days 1/1/2017 2/1/2017 3/1/2017 4/1/2017 ......................................... 30/1/2017 (All days for month)
Yasser Math - Math - -
English - - - -
Mark Math - - - -
我怎样才能做到这一点?
谢谢
我猜该脚本将需要太复杂的动态编码,我刚刚创建了一个架构,但是要花费太多的精力来转换为完整的动态SQL脚本
;with cte as (
select distinct StudentName, SubjectName, [DateTime] from studentCTE
), cte2 as (
select
StudentName,
case when [DateTime] = '2017-01-01' then SubjectName else null end as '2017-01-01',
case when [DateTime] = '2017-03-01' then SubjectName else null end as '2017-03-01',
case when [DateTime] = '2017-06-01' then SubjectName else null end as '2017-06-01'
from cte
)
SELECT distinct
StudentName,
STUFF(
(
SELECT
',' + [2017-01-01]
FROM cte2 C
where c.StudentName = cte2.StudentName
FOR XML PATH('')
), 1, 1, ''
) As '2017-01-01',
STUFF(
(
SELECT
',' + [2017-03-01]
FROM cte2 C
where c.StudentName = cte2.StudentName
FOR XML PATH('')
), 1, 1, ''
) As '2017-03-01',
STUFF(
(
SELECT
',' + [2017-06-01]
FROM cte2 C
where c.StudentName = cte2.StudentName
FOR XML PATH('')
), 1, 1, ''
) As '2017-06-01'
from cte2
我希望它能以某种方式有所帮助,但是我想在将主体名称字段进行SQL串联之后,可以通过动态sql数据透视表解决以下查询
请检查以下动态SQL数据透视查询
DECLARE @PivotColumnHeaders VARCHAR(MAX)
SELECT @PivotColumnHeaders =
COALESCE(
@PivotColumnHeaders + ',[' + convert(nvarchar(20),date,23) + ']',
'[' + convert(nvarchar(20),date,23) + ']'
)
FROM dbo.GetFullMonth(getdate())
DECLARE @PivotTableSQL NVARCHAR(MAX)
SET @PivotTableSQL = N'
SELECT *
FROM (
select distinct StudentName,
STUFF(
(
SELECT
'','' + SubjectName
FROM studentCTE C
where c.StudentName = studentCTE.StudentName
and c.DateTime = studentCTE.DateTime
FOR XML PATH('''')
), 1, 1, ''''
) As Subjects
, [DateTime]
from studentCTE
) AS PivotData
PIVOT (
MAX(Subjects)
FOR [DateTime] IN (
' + @PivotColumnHeaders + '
)
) AS PivotTable
'
EXECUTE(@PivotTableSQL)
这是我的输出
总结一下查询,首先我需要将当月的日期作为列名。 我在给定的参考中使用了日历功能模块 GetFullMonth。 我只是将返回的“ datetime”列更改为“ date”数据类型。
正如我在先前的代码示例中指出的那样,我将SQL串联与FOR XML PATH方法结合使用。
我想与您分享最后一个参考。 我在动态查询的PivotColumnHeaders部分中使用了日期到字符串的转换,在其中定义了其他数据透视列。 我使用的转换参数为23。您可以在给定的参考处检查datetime格式参数的完整列表。
希望这些对您有所帮助,
如果要日期列仅包含表中的内容,则必须使用此查询。 DECLARE @DYNQRY AS VARCHAR(MAX) ,@COL AS VARCHAR(MAX) SELECT @COL= ISNULL(@COL + ',','') + QUOTENAME(DATE) FROM (SELECT DISTINCT DATE FROM STUDENTSUBJECT) AS DATE SET @DYNQRY ='SELECT STUDENTNAME, ' + @COL + ' FROM (SELECT A.STUDENTID,STUDENTNAME,SUBJECTNAME,DATE FROM STUDENT A,SUBJECT B,STUDENTSUBJECT C WHERE A.STUDENTID=C.STUDENTID AND B.SUBJECTID=C.SUBJECTID )A PIVOT( MAX(SUBJECTNAME) FOR DATE IN (' + @COL + ') ) AS PVTTABLE' EXEC (@DYNQRY)
CREATE TABLE #tt(StudentID INT,StudentName VARCHAR(200),SubjectID INT,SubjectName VARCHAR(200),[DateTime]DATETIME)
INSERT INTO #tt
SELECT 1,'Yasser',1,'Math','01/01/2017' UNION
SELECT 1,'Yasser',1,'English','01/01/2017' UNION
SELECT 1,'Yasser',1,'Math','01/03/2017' UNION
SELECT 1,'Mark',1,'Math','01/01/2017' UNION
SELECT 1,'John',1,'Math','01/06/2017'
DECLARE @col1 VARCHAR(max),@col2 VARCHAR(max),@sql VARCHAR(max)
SELECT @col1=ISNULL(@col1+',','')+ t.d
,@col2=ISNULL(@col2+',','')+'ISNULL('+ t.d +',''-'') AS '+t.d
FROM #tt
INNER JOIN master.dbo.spt_values AS sv ON sv.type='P' AND sv.number BETWEEN 0 AND 30
CROSS APPLY(VALUES('['+CONVERT(VARCHAR,DATEADD(dd,sv.number,DATEADD(MONTH, MONTH([DateTime])-1,DATEADD(YEAR,YEAR([DateTime])-1900,0))),110)+']')) t(d)
WHERE MONTH(DATEADD(dd,sv.number,DATEADD(MONTH, MONTH([DateTime])-1,DATEADD(YEAR,YEAR([DateTime])-1900,0))))= MONTH([DateTime])
GROUP BY MONTH([DateTime]),YEAR([DateTime]),sv.number,t.d
PRINT @col2
SET @sql='
SELECT StudentID,StudentName,'+@col2+' FROM #tt
PIVOT(max(SubjectName) FOR [DateTime] IN ('+@col1+')) p'
EXEC (@sql)
-部分栏-
StudentID StudentName 01-01-2017 01-02-2017 01-03-2017 01-04-2017 01-05-2017 01-06-2017 01-07-2017 01-08-2017 01-09-2017 01-10-2017 01-11-2017 1 John - - - - - Math - - - - - 1 Mark Math - - - - - - - - - - 1 Yasser Math - Math - - - - - - - -
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.