[英]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.