簡體   English   中英

轉置和擴展列數據集T-SQL

[英]Transposing and Expanding Columnar Dataset T-SQL

我有一個SQL表,看起來像下面我在excel中編寫的示例: 樣本數據集


以下是我想要的結果。 我需要將上面的數據轉換為2列列表:

所需結果


以防萬一需要更多信息,這是第一張圖片,並帶有說明我為什么使用行的注釋: 輸入表+注釋

UnPivot當然可以提高性能,但是如果您想在不實際使用Dynamic SQL的情況下動態取消數據透視,請考慮以下內容

Select A.fruiteater
      ,C.*
 From  fruits A
 Cross Apply ( values (cast((Select A.* for XML RAW) as xml))) B(XMLData)
 Cross Apply (
                Select Item  = a.value('local-name(.)','varchar(100)')
                      ,Value = a.value('.','varchar(max)') 
                 From  B.XMLData.nodes('/row')  as C1(n)
                 Cross Apply C1.n.nodes('./@*') as C2(a)
                 Where a.value('local-name(.)','varchar(100)') not in ('fruiteater','OtherColumnsToExclude')
             ) C

退貨

fruiteater  Item    Value
Aaron       Fruit1  Orange
Aaron       Fruit2  Pear
Aaron       Fruit3  Apple
Bob         Fruit1  Apple
Bob         Fruit2  Orange
Bob         Fruit3  Blueberries
Bob         Fruit4  Peach
Bob         Fruit5  Mango
Bob         Fruit6  Banana
Carter      Fruit1  Pear
Carter      Fruit2  Orange
Carter      Fruit3  Apple
David       Fruit1  Blueberries
Earnest     Fruit1  Mango
Earnest     Fruit2  Orange
Earnest     Fruit3  Pear
Earnest     Fruit4  Apple
Earnest     Fruit5  Blueberries
Frank       Fruit1  Raspberries

您可能要使用Unpivot以獲得預期的結果。

create table fruits (fruiteater varchar(100), Fruit1 varchar(100), Fruit2 varchar(100), 
Fruit3 varchar(100), Fruit4 varchar(100), Fruit5 varchar(100), Fruit6 varchar(100))  

insert into fruits values ('Aaron', 'Orange', 'Pear', 'Apple', NULL, NULL, NULL) 
,('Bob', 'Apple', 'Orange', 'Blueberries', 'Peach', 'Mango', 'Banana') 
,('Carter', 'Pear', 'Orange', 'Apple', NULL, NULL, NULL) 
,('David', 'Blueberries', NULL, NULL, NULL, NULL, NULL) 
,('Earnest', 'Mango', 'Orange', 'Pear', 'Apple','Blueberries', NULL) 
,('Frank', 'Raspberries', NULL, NULL, NULL, NULL, NULL) 

由於所有這些結果都將放在一列中,因此在進行數據透視時要注意數據類型和長度非常重要,因此我確保所有列都屬於同一數據類型。

select fruiteater, Value as Fruit from fruits
unpivot 
(value for columnname in ([Fruit1], [Fruit2], [Fruit3], [Fruit4], [Fruit5],[Fruit6]))unpvt 

輸出:Unpivot將處理空值,因為它消除了這一點。

fruiteater  Fruit
Aaron   Orange
Aaron   Pear
Aaron   Apple
Bob     Apple
Bob     Orange
Bob     Blueberries
Bob     Peach
Bob     Mango
Bob     Banana
Carter  Pear
Carter  Orange
Carter  Apple
David   Blueberries
Earnest Mango
Earnest Orange
Earnest Pear
Earnest Apple
Earnest Blueberries
Frank   Raspberries

為此,我更喜歡使用橫向連接( apply )。 我認為語法更簡單,除非您明確希望這樣做,否則它不會做任何“魔術”操作,例如刪除NULL值:

select f.fruiteater, v.fruit
from fruits f cross apply
     (values (fruit1),  (fruit2),  (fruit3), (fruit4), (fruit5), (fruit6)
     ) v(fruit)
where v.fruit is not null;

更重要的是, unpivot是一種非常特定的語法,用於一種目的。 橫向連接非常靈活和強大。 使用它們來進行透視是了解它們的一種非常簡單的方法。

暫無
暫無

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

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