簡體   English   中英

在SQL Server 2008中將行轉換為列

[英]Convert Rows to Column In SQL Server 2008

我想使用Pivot將行轉換為列。

我有三個表:

  1. 帶有列StudentIDStudentName Student
  2. Subject表中包含SubjectIDSubjectName
  3. Student Subject的列表StudentSubjectIDStudentIDSubjectIDDate

現在,我編寫了一個查詢以從上述表中獲取數據

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM