Bạn chỉ cần tách các cột sau khi thực hiện UNPIVOT
một cái gì đó như thế này:
WITH Unpivoted
AS
(
SELECT region, lob, columns, value
FROM Regions
UNPIVOT
(
columns
FOR value IN([GWP 2013] , [GWP 2014] ,
[LR 2013] , [LR 2014] ,
[GWP 2015], [LR 2015])
) AS u
)
SELECT
region,
lob,
columns,
CAST(CASE WHEN value LIKE 'GWP%' THEN REPLACE(value,'GWP ', '')
WHEN value LIKE 'LR%' THEN REPLACE(value,'LR ', '')
END AS INT) AS Year,
CASE WHEN value LIKE 'GWP%' THEN 'GWP'
WHEN value LIKE 'LR%' THEN 'LR'
END AS Metrics
FROM Unpivoted;
Và sau đó, tất nhiên bạn nên thực hiện động để tránh liệt kê các cột theo cách thủ công và thực hiện động:
DECLARE @cols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
select @cols = STUFF((SELECT distinct ',' +
QUOTENAME(column_name)
FROM information_schema.columns
WHERE table_name = 'Regions'
AND COLUMN_NAME <> 'Region'
AND COLUMN_NAME <> 'LOB'
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');
SELECT @query = 'WITH Unpivoted
AS
(
SELECT region, lob, columns, value
FROM Regions
UNPIVOT
(
columns
FOR value IN('+ @cols + ')
) AS u
)
SELECT
region,
lob,
columns,
CAST(CASE WHEN value LIKE ''GWP%'' THEN REPLACE(value,''GWP '', '''')
WHEN value LIKE ''LR%'' THEN REPLACE(value,''LR '', '''')
END AS INT) AS Year,
CASE WHEN value LIKE ''GWP%'' THEN ''GWP''
WHEN value LIKE ''LR%'' THEN ''LR''
END AS Metrics
FROM Unpivoted';
EXECUTE(@query);
Điều này sẽ hoạt động tốt nếu giả sử rằng:
- Tất cả các cột
[GWP 2013] , [GWP 2014] , [LR 2013] , [LR 2014] , [GWP 2015], [LR 2015], ... etc
có cùng định dạng (GWP hoặc LR, sau đó là dấu cách rồi đến năm và -
Tất cả các cột có cùng kiểu dữ liệu
int
hoặc thập phân, nếu các kiểu dữ liệu không giống nhau, bạn nên chuyển tất cả chúng thành một kiểu dữ liệu trước khi thực hiệnunpivot
nếu không bạn sẽ gặp lỗi.
Điều này sẽ cung cấp cho bạn:
| region | lob | columns | Year | Metrics |
|--------|---------|----------|------|---------|
| North | Workers | 38902.5 | 2013 | GWP |
| North | Workers | 37972404 | 2014 | GWP |
| North | Workers | 70 | 2015 | GWP |
| North | Workers | 89 | 2013 | LR |
| North | Workers | 82 | 2014 | LR |
| North | Workers | 80 | 2015 | LR |
Cập nhật:
Tôi đã sử dụng FOR XML PATH('') ..
để nối tất cả danh sách các giá trị trong một chuỗi, đó là một công việc xung quanh trong SQL Server để làm điều đó. Giá trị của @cols
sẽ là chuỗi:[GWP 2013], [GWP 2014], ...
.
Nếu kiểu dữ liệu trường của bạn khác, bạn phải thực hiện ép kiểu của tất cả các cột sẽ được bỏ phân chia trong truy vấn liên kết trước khi thực hiện UNPVOT
như thế này:
SELECT @query = 'WITH Unpivoted
AS
(
SELECT region, lob, columns, value
FROM
(
SELECT
region,
lob,
CAST([GWP 2013] AS DECIMAL(10,2)) AS [GWP 2013],
CAST([GWP 2014] AS DECIMAL(10,2)) AS [GWP 2014],
... etc
FROM Regions
) AS t
UNPIVOT
(
columns
FOR value IN('+ @cols + ')
) AS u
)
SELECT
region,
lob,
columns,
CAST(CASE WHEN value LIKE ''GWP%'' THEN REPLACE(value,''GWP '', '''')
WHEN value LIKE ''LR%'' THEN REPLACE(value,''LR '', '''')
END AS INT) AS Year,
CASE WHEN value LIKE ''GWP%'' THEN ''GWP''
WHEN value LIKE ''LR%'' THEN ''LR''
END AS Metrics
FROM Unpivoted';
Nếu bạn cảm thấy khó khăn khi viết truyền cho tất cả các cột theo cách thủ công, bạn có thể tạo động và nối nó thay thế, ví dụ:
DECLARE @colsCasted AS NVARCHAR(MAX);
select @colsCasted = STUFF((SELECT distinct ',' +
'CAST(' + QUOTENAME(column_name) + 'AS DECIMAL(10,2)) AS ' + QUOTENAME(column_name)
FROM information_schema.columns
WHERE table_name = 'Regions'
AND COLUMN_NAME <> 'Region'
AND COLUMN_NAME <> 'LOB'
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');
Sau đó, trong truy vấn động, hãy nối giá trị đó vào nó:
SELECT @query = 'WITH Unpivoted
AS
(
SELECT region, lob, columns, value
FROM
(
SELECT region, lob,
' + @colsCasted + '
FROM Regions
) AS t
UNPIVOT
(
columns
FOR value IN('+ @cols + ')
) AS u
)
SELECT
region,
lob,
columns,
CAST(CASE WHEN value LIKE ''GWP%'' THEN REPLACE(value,''GWP '', '''')
WHEN value LIKE ''LR%'' THEN REPLACE(value,''LR '', '''')
END AS INT) AS Year,
CASE WHEN value LIKE ''GWP%'' THEN ''GWP''
WHEN value LIKE ''LR%'' THEN ''LR''
END AS Metrics
FROM Unpivoted';
EXECUTE(@query);