簡體   English   中英

如何與SQL Server中的FOR XML PATH一起進行數據透視?

[英]How to do pivoting in conjunction with FOR XML PATH in SQL Server?

我有一個輸入

DECLARE @T TABLE(SName VARCHAR(20), Subject VARCHAR(20), Marks INT, ExamDate  DATE)

INSERT INTO @T
SELECT 'A', 'Subject1', 77, '2011-01-01' UNION ALL
SELECT 'A', 'Subject2', 97, '2011-01-01' UNION ALL
SELECT 'B', 'Subject1', 80 ,'2012-04-01' UNION ALL
SELECT 'B', 'Subject2', 70, '2012-03-01' UNION ALL
SELECT 'C', 'Subject1', 44, '2011-01-01' UNION ALL
SELECT 'C', 'Subject2', 90, '2011-01-01' UNION ALL
SELECT 'D', 'Subject1', 79 ,'2012-04-01' UNION ALL
SELECT 'D', 'Subject2', 66, '2012-03-01'

SELECT X.*
FROM ( SELECT
        t.*
        ,Rn = DENSE_RANK() OVER(PARTITION BY t.Subject ORDER BY t.Marks DESC)
FROM @T t) X WHERE X.Rn = 3

輸出:

SName   Subject   Marks ExamDate        Rn
A       Subject1    77  2011-01-01       3
B       Subject2    70  2012-03-01       3

我正在尋找輸出

SName   Subject1    Subject2
-----   --------    --------
A       77          
B                   70  

這意味着,由於我們正在尋找學生的第三高分,因此,哪個學生獲得了第三高分,都應該進入最終的期望列表。

如果學生A和C(說)在科目1之間並列平分,而學生C在學科3(說)中獲得第三高分,那么輸出將是

SName   Subject1    Subject2    Subject3
-----   --------    --------    ---------
A,C     77          
B                   70  
C                               78  

第二個的DDL如下

DECLARE @T TABLE(SName VARCHAR(20), Subject VARCHAR(20), Marks INT, ExamDate  DATE)

INSERT INTO @T
SELECT 'A', 'Subject1', 77, '2011-01-01' UNION ALL
SELECT 'A', 'Subject2', 97, '2011-01-01' UNION ALL
SELECT 'A', 'Subject3', 99, '2011-01-01' UNION ALL
SELECT 'B', 'Subject1', 80 ,'2012-04-01' UNION ALL
SELECT 'B', 'Subject2', 70, '2012-03-01' UNION ALL
SELECT 'B', 'Subject3', 88, '2012-03-01' UNION ALL
SELECT 'C', 'Subject1', 77, '2011-01-01' UNION ALL
SELECT 'C', 'Subject2', 90, '2011-01-01' UNION ALL
SELECT 'C', 'Subject3', 78, '2011-01-01' UNION ALL
SELECT 'D', 'Subject1', 79 ,'2012-04-01' UNION ALL
SELECT 'D', 'Subject2', 66, '2012-03-01' UNION ALL
SELECT 'D', 'Subject3', 77, '2012-03-01'


SELECT X.*
FROM ( SELECT
        t.*
        ,Rn = DENSE_RANK() OVER(PARTITION BY t.Subject ORDER BY t.Marks DESC)
FROM @T t) X WHERE X.Rn = 3

我認為應該通過使用FOR XML PATHPIVOT來完成。 但是如何?

提前致謝

如您所述,您需要將XML + STUFFPIVOT結合使用:

DECLARE @rn INT = 3;

;WITH cte AS
(
  SELECT X.*
  FROM ( SELECT t.*
        ,Rn = DENSE_RANK() OVER(PARTITION BY t.Subject ORDER BY t.Marks DESC)
        FROM @T t) X WHERE X.Rn = @rn
), cte2 AS
(
  SELECT DISTINCT Subject, Marks,
        [SName] =  STUFF((SELECT ',' + SName
                   FROM cte c2
                   WHERE c1.Subject = c2.Subject
                   ORDER BY SName
                   FOR XML PATH('')),1,1,'')
  FROM cte c1
)
SELECT SName, [Subject1],[Subject2], [Subject3]
FROM cte2
PIVOT
(
  MAX(Marks)
  FOR Subject IN ([Subject1],[Subject2], [Subject3])
) AS piv;

LiveDemo

輸出:

╔═══════╦══════════╦══════════╦══════════╗
║ SName ║ Subject1 ║ Subject2 ║ Subject3 ║
╠═══════╬══════════╬══════════╬══════════╣
║ A,C   ║       77 ║          ║          ║
║ B     ║          ║       70 ║          ║
║ C     ║          ║          ║       78 ║
╚═══════╩══════════╩══════════╩══════════╝

暫無
暫無

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

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