มีหลายวิธีที่คุณสามารถแปลงข้อมูลนี้ได้ ในโพสต์ต้นฉบับของคุณคุณระบุว่าPIVOT
ดูเหมือนจะซับซ้อนเกินไปสำหรับสถานการณ์นี้ แต่สามารถนำไปใช้ได้อย่างง่ายดายโดยใช้ทั้งฟังก์ชันUNPIVOT
และPIVOT
ใน SQL Server
อย่างไรก็ตามหากคุณไม่สามารถเข้าถึงฟังก์ชันเหล่านี้ได้สิ่งนี้สามารถจำลองแบบได้โดยใช้UNION ALL
to 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()
กับงบที่จะได้รับคอลัมน์ใหม่สำหรับแต่ละcase
color
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 |