簡體   English   中英

將多行數據合並為單行-SQL Server

[英]Multiple rows of data into a single row - SQL Server

我有一張看起來像這樣的桌子

ID          NAME          MODULE          STARTDATE          ENDDATE          MARK
123456      J Bloggs      Module 1        13/01/2014         30/04/2014       FAIL
123456      J Bloggs      Module 1        13/05/2014         30/08/2014       FAIL
123456      J Bloggs      Module 1        13/09/2014         30/12/2014       PASS
123456      J Bloggs      Module 2        13/05/2014         30/08/2014       PASS
123456      J Bloggs      Module 3        13/01/2015         30/04/2015       FAIL
234567      A Test        Module 1        13/01/2014         30/04/2014       PASS
234567      A Test        Module 2        13/05/2014         30/08/2014       FAIL
234567      A Test        Module 2        13/09/2014         30/12/2014       PASS

該表包含大量數據,其結構與此類似。 我試圖做的是根據學生和所采用的模塊將多行中的某些數據幾乎連接成一個行結構,因此最終結果看起來像

ID          NAME          MODULE          ENDDATE1          ENDDATE2          ENDDATE3          MARK
123456      J Bloggs      Module 1        30/04/2014        30/08/2014        30/12/2014        PASS
123456      J Bloggs      Module 2        30/08/2014                                            PASS
123456      J Bloggs      Module 3        30/04/2015                                            FAIL
234567      A Test        Module 1        30/04/2014                                            PASS
234567      A Test        Module 2        30/08/2014        30/12/2014                          PASS

因此,新表格將基於模塊在同一行上顯示所有結束日期,然后將顯示最新標記'max(Mark)'。 示例表中顯示的結束日期可能超過3個,因為這將完全取決於原始表以及學生可能不得不“重新安置”模塊的次數(最多4/5)。有時)。

嘗試使用Dynamic Pivot:

IF(OBJECT_ID('tempdb..#table') IS NOT NULL)
DROP TABLE #TABLE
CREATE TABLE  #TABLE (ID INT, NAME VARCHAR(30),MODULE VARCHAR(30),STARTDATE VARCHAR(30),ENDDATE VARCHAR(30),MARK VARCHAR(30))

INSERT INTO #TABLE VALUES
(123456, 'J Bloggs', 'Module 1', '13/01/2014', '30/04/2014', 'FAIL'),
(123456, 'J Bloggs', 'Module 1', '13/05/2014', '30/08/2014', 'FAIL'),
(123456, 'J Bloggs', 'Module 1', '13/09/2014', '30/12/2014', 'PASS'),
(123456, 'J Bloggs', 'Module 2', '13/05/2014', '30/08/2014', 'PASS'),
(123456, 'J Bloggs', 'Module 3', '13/01/2015', '30/04/2015', 'FAIL'),
(234567, 'A Test', 'Module 1', '13/01/2014', '30/04/2014', 'PASS'),
(234567, 'A Test', 'Module 2', '13/05/2014', '30/08/2014', 'FAIL'),
(234567, 'A Test', 'Module 2', '13/09/2014', '30/12/2014', 'PASS')
DECLARE @Columns VARCHAR(MAX)

SELECT @Columns = STUFF((SELECT ',' + '[' + CONVERT(VARCHAR(30), number, 121) + ']'
                         FROM   master..spt_values N
                         WHERE  n.number BETWEEN 1 AND (SELECT TOP 1 COUNT(Enddate)
                                                        FROM   #TABLE
                                                        GROUP  BY ID,NAME,MODULE
                                                        ORDER  BY COUNT(Enddate) DESC)
                                AND TYPE = 'P'
                         FOR XML PATH('')), 1, 1, '')
DECLARE @sql NVARCHAR(MAX) = '
SELECT ID,
       NAME,
       MODULE,
       '+@Columns+',
       (SELECT TOP 1 MARK
        FROM   #table t1
        WHERE  pvt.ID = t1.ID
               AND pvt.NAME = t1.NAME
               AND pvt.MODULE = t1.MODULE
        ORDER  BY enddate DESC) AS MARK
FROM   (SELECT ID,
               NAME,
               MODULE,
               ENDDATE,
               ROW_NUMBER()
                 OVER(
                   partition BY ID, NAME, MODULE
                   ORDER BY enddate) AS rn
        FROM   #table) t
       PIVOT ( Max(ENDDATE)
             FOR rn IN('+@Columns+')) AS pvt 
'

EXEC sp_executeSQL @sql

在此處檢查“透視”和“取消透視”的詳細信息。

注意:如您所見,我使用子查詢來查找最新的Mark 我盡力用更好的東西代替它,但是我做不到。 盡管如此,它將為您工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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