มีหลายวิธีที่คุณสามารถแปลงข้อมูลนี้ได้ ในโพสต์ต้นฉบับของคุณคุณระบุว่าPIVOTดูเหมือนจะซับซ้อนเกินไปสำหรับสถานการณ์นี้ แต่สามารถนำไปใช้ได้อย่างง่ายดายโดยใช้ทั้งฟังก์ชันUNPIVOTและPIVOTใน SQL Server
อย่างไรก็ตามหากคุณไม่สามารถเข้าถึงฟังก์ชันเหล่านี้ได้สิ่งนี้สามารถจำลองแบบได้โดยใช้UNION ALLto UNPIVOTและฟังก์ชันรวมที่มีCASEคำสั่งเพื่อPIVOT:
สร้างตาราง:
CREATE TABLE yourTable([color] varchar(5), [Paul] int, [John] int, [Tim] int, [Eric] int);
INSERT INTO yourTable
([color], [Paul], [John], [Tim], [Eric])
VALUES
('Red', 1, 5, 1, 3),
('Green', 8, 4, 3, 5),
('Blue', 2, 2, 9, 1);
Union All, Aggregate และ CASE Version:
select name,
sum(case when color = 'Red' then value else 0 end) Red,
sum(case when color = 'Green' then value else 0 end) Green,
sum(case when color = 'Blue' then value else 0 end) Blue
from
(
select color, Paul value, 'Paul' name
from yourTable
union all
select color, John value, 'John' name
from yourTable
union all
select color, Tim value, 'Tim' name
from yourTable
union all
select color, Eric value, 'Eric' name
from yourTable
) src
group by name
ดูSQL Fiddle พร้อมการสาธิต
UNION ALLดำเนินการUNPIVOTของข้อมูลโดยการเปลี่ยนคอลัมน์Paul, John, Tim, Ericเป็นแถวแยกต่างหาก แล้วคุณใช้ฟังก์ชันการรวมsum()กับงบที่จะได้รับคอลัมน์ใหม่สำหรับแต่ละcasecolor
Unpivot และ Pivot Static Version:
ทั้งฟังก์ชันUNPIVOTและPIVOTฟังก์ชันในเซิร์ฟเวอร์ SQL ทำให้การเปลี่ยนแปลงนี้ง่ายขึ้นมาก หากคุณทราบค่าทั้งหมดที่ต้องการแปลงคุณสามารถฮาร์ดโค้ดให้เป็นเวอร์ชันคงที่เพื่อให้ได้ผลลัพธ์:
select name, [Red], [Green], [Blue]
from
(
select color, name, value
from yourtable
unpivot
(
value for name in (Paul, John, Tim, Eric)
) unpiv
) src
pivot
(
sum(value)
for color in ([Red], [Green], [Blue])
) piv
ดูSQL Fiddle พร้อมการสาธิต
แบบสอบถามภายในที่UNPIVOTมีฟังก์ชันเดียวกับUNION ALL. ใช้รายการคอลัมน์และเปลี่ยนเป็นแถวPIVOTจากนั้นทำการแปลงขั้นสุดท้ายเป็นคอลัมน์
เวอร์ชันไดนามิก Pivot:
หากคุณมีจำนวนคอลัมน์ที่ไม่รู้จัก ( Paul, John, Tim, Ericในตัวอย่างของคุณ) และจำนวนสีที่ไม่รู้จักในการแปลงคุณสามารถใช้ dynamic sql เพื่อสร้างรายการUNPIVOTจากนั้นPIVOT:
DECLARE @colsUnpivot AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@colsPivot as NVARCHAR(MAX)
select @colsUnpivot = stuff((select ','+quotename(C.name)
from sys.columns as C
where C.object_id = object_id('yourtable') and
C.name <> 'color'
for xml path('')), 1, 1, '')
select @colsPivot = STUFF((SELECT ','
+ quotename(color)
from yourtable t
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query
= 'select name, '+@colsPivot+'
from
(
select color, name, value
from yourtable
unpivot
(
value for name in ('+@colsUnpivot+')
) unpiv
) src
pivot
(
sum(value)
for color in ('+@colsPivot+')
) piv'
exec(@query)
ดูSQL Fiddle พร้อมการสาธิต
รุ่นแบบไดนามิก queries ทั้งสองyourtableแล้วsys.columnsตารางในการสร้างรายชื่อของรายการไปและUNPIVOT PIVOTจากนั้นจะเพิ่มลงในสตริงการสืบค้นที่จะดำเนินการ ข้อดีของเวอร์ชันไดนามิกคือหากคุณมีรายการที่เปลี่ยนแปลงcolorsและ / หรือnamesสิ่งนี้จะสร้างรายการในขณะรันไทม์
คำค้นหาทั้งสามจะให้ผลลัพธ์เดียวกัน:
| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric | 3 | 5 | 1 |
| John | 5 | 4 | 2 |
| Paul | 1 | 8 | 2 |
| Tim | 1 | 3 | 9 |