Sql-Server

SQL:透視非數字數據

  • September 1, 2020

我有一組數據,基本上如下所示:

+---------+--------+
| EventId | Field  |
+---------+--------+
|       1 | apple  |
|       1 | paper  |
|       1 | boy    |
|       2 | banana |
|       2 | cat    |
|       3 | girl   |
+---------+--------+

我想把它變成這樣:

+-------+--------+------+
|   1   |   2    |  3   |
+-------+--------+------+
| apple | banana | girl |
| paper | cat    |      |
| boy   |        |      |
+-------+--------+------+

我試圖擺弄PIVOT,但我無法得到我想要的結果。我在查看或使用錯誤的命令嗎?這PIVOT是正確的關係運算符嗎?

這是我到目前為止一直在處理的程式碼:

DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);
SET @columns = N'';
SELECT @columns += N', ' + QUOTENAME(EventID)
 FROM (
           select distinct
               EventId
           from Events
       ) AS x;

SET @sql = 
N'select  ' + 
STUFF(@columns, 1, 2, '') +  ' 

into ##tempMap from
(
   select
       ev.EventID,ev.FieldName
   from Events ev
) as a
pivot 
(
     max(FieldName) for EventId in ('
 + STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '')
 + ')
) as pivottable;';

EXEC sp_executesql @sql

select * from ##tempMap
drop table ##tempMap

由於MAX聚合函式,上面的程式碼返回以下結果。

+-------+-----+------+
|   1   |  2  |  3   |
+-------+-----+------+
| paper | cat | girl |
+-------+-----+------+

這個答案不是動態的,而是向您展示如何在純 TSQL 中實現目標,使其動態化應該很簡單。

本質上,您只需要添加另一列來分散數據,這樣 MAX(fieldname) 就不是事件的最大值。我選擇使用由 EventID 分區的 ROW_NUMBER,以便每個事件的每個條目也被編號。

我也看過https://stackoverflow.com/questions/1343145/tsql-pivot-without-aggregate-function

DROP TABLE IF EXISTS ##Events 

CREATE TABLE ##Events 
   (
   EventID INT NOT NULL
   , FieldName VARCHAR(20) NOT NULL
   )

INSERT INTO ##Events 
   (EventID, FieldName)
VALUES (1, 'apple')
   , (1, 'paper')
   , (1, 'boy')
   , (2, 'banana')
   , (2, 'cat')
   , (3, 'girl')

;WITH CTE_RN AS 
   (
   SELECT EventID
       , FieldName 
       , RN = ROW_NUMBER() OVER (PARTITION BY EventID ORDER BY FieldName)
   FROM ##Events AS E
   )
SELECT [1]
   , [2]
   , [3]
FROM CTE_RN
   PIVOT (MAX(FieldName) FOR EventID IN ([1], [2], [3])) AS pvt

引用自:https://dba.stackexchange.com/questions/274540