我在处理数据表方面遇到问题:
我该如何转换:
您是否足够友善地给我提示(不是完整的代码)怎么做?我真的不知道我应该从哪里开始(我不知道这是否是典型的枢轴旋转)
+------+------+--------+----------+-----------+-----+
| ColI | Col2 | Month | Turnover | Provision | Fee |
+------+------+--------+----------+-----------+-----+
| 123 | Asdf | 201810 | 10000 | 100 | 0,1 |
| 123 | Asdf | 201811 | 20000 | 200 | 0,2 |
| 123 | Asdf | 201812 | 30000 | 300 | 0,3 |
+------+------+--------+----------+-----------+-----+
对此:
+------+------+---------------+-----------------+------------+---------------+-----------------+------------+---------------+-----------------+-----------+
| ColI | Col2 | Turnover20810 | Provision201810 | Fee201810 | Turnover20811 | Provision201811 | Fee201811 | Turnover20812 | Provision201812 | Fee201812 |
+------+------+---------------+-----------------+------------+---------------+-----------------+------------+---------------+-----------------+-----------+
| 123 | Asdf | 10000 | 100 | 0,1 | 20000 | 200 | 0,2 | 30000 | 300 | 0,3 |
+------+------+---------------+-----------------+------------+---------------+-----------------+------------+---------------+-----------------+-----------+
谢谢!
答案 0 :(得分:3)
假设每个ColI, Col2
组最多只有三个记录,那么我们可以尝试在ROW_NUMBER
的帮助下进行数据透视:
WITH cte AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY ColI, Col2 ORDER BY Month) rn
FROM yourTable
)
SELECT
ColI,
Col2,
MAX(CASE WHEN rn = 1 THEN Turnover END) AS Turnover1,
MAX(CASE WHEN rn = 1 THEN Provision END) AS Provision1,
MAX(CASE WHEN rn = 1 THEN Fee END) AS Fee1,
MAX(CASE WHEN rn = 2 THEN Turnover END) AS Turnover2,
MAX(CASE WHEN rn = 2 THEN Provision END) AS Provision2,
MAX(CASE WHEN rn = 2 THEN Fee END) AS Fee2,
MAX(CASE WHEN rn = 3 THEN Turnover END) AS Turnover3,
MAX(CASE WHEN rn = 3 THEN Provision END) AS Provision3,
MAX(CASE WHEN rn = 3 THEN Fee END) AS Fee3
FROM cte
GROUP BY
ColI,
Col2;
请注意,我并没有硬性规定更具体的列名,以使查询尽可能通用。例如,也许可能还有另一个ColI, Col2
组,它们的三个月时间会有所不同。
答案 1 :(得分:2)
通过使用动态Sql
IF OBJECT_ID('tempdb..#TEMP') IS NOT NULL
DROP TABLE #TEMP
;WITH CTE (ColI , Col2 , Month , Turnover , Provision , Fee )
AS
(
SELECT 123 , 'Asdf' , 201810 , 10000 ,100 ,'0,1' UNION ALL
SELECT 123 , 'Asdf' , 201811 , 20000 ,200 , '0,2' UNION ALL
SELECT 123 , 'Asdf' , 201812 , 30000 ,300 , '0,3'
)
SELECT ColI , Col2,Turnover , Provision , Fee,MixedCol,Reqcol , ROW_NUMBER()OVER(ORDER BY (SELECT NULL)) AS Seq
INTO #Temp
FROM CTE
CROSS APPLY (VALUES (CONCAT('Turnover','_',[Month]),CAST(Turnover AS VARCHAR(20))),
(CONCAT('Provision','_',[Month]),CAST(Provision AS VARCHAR(20))),
(CONCAT('Fee','_',[Month]),CAST(Fee AS VARCHAR(20)))
)DT (MixedCol,Reqcol)
DECLARE @Sql nvarchar(max),
@DynamicColumn nvarchar(max),
@MaxDynamicColumn nvarchar(max)
SELECT @DynamicColumn = STUFF((SELECT ', '+QUOTENAME(CAST(MixedCol AS VARCHAR(100)))
FROM #TEMP ORDER BY Seq FOR XML PATH ('')),1,1,'')
SELECT @MaxDynamicColumn = STUFF((SELECT ', '+'MAX('+QUOTENAME(CAST(MixedCol AS VARCHAR(100)))+') AS '+QUOTENAME(CAST(MixedCol AS VARCHAR(100)))
FROM #TEMP ORDER BY Seq FOR XML PATH ('')),1,1,'')
SET @Sql=' SELECT ColI , Col2,'+ @MaxDynamicColumn+'
FROM
(
SELECT * FROM #TEMP
)AS src
PIVOT
(
MAX(Reqcol) FOR [MixedCol] IN ('+@DynamicColumn+')
) AS Pvt
GROUP BY ColI , Col2 '
EXEC (@Sql)
PRINT @Sql
答案 2 :(得分:0)
Q:“ ...给我提示(不是完整的代码)如何执行此操作”
A:此示例具有表的动态转置。你可以试试看取消旋转原始表格并转置。
CREATE table #tbl (
color varchar(10), Paul int, John int, Tim int, Eric int);
insert #tbl select
'Red' ,1 ,5 ,1 ,3 union all select
'Green' ,8 ,4 ,3 ,5 union all select
'Blue' ,2 ,2 ,9 ,1;
select * FROM #tbl
--1) Transpose. Example without dynamic code. You create list of fields in query
select *
from #tbl
unpivot (value for name in ([Paul],[John],[Tim],[Eric])) up
pivot (max(value) for color in ([Blue],[Green],[Red])) p
--2) Transpose. Example with dynamic code, without names of fields.
DECLARE @cols NVARCHAR(MAX), @query NVARCHAR(MAX), @rows NVARCHAR(MAX)='';
-- XML with all values
SET @cols = STUFF(
(
SELECT DISTINCT
','+QUOTENAME(T.Color) -- Name of first column
FROM #tbl T FOR XML PATH(''), TYPE
).value('.', 'nvarchar(max)'), 1, 1, '');
SELECT @rows=@rows+','+QUOTENAME(Name)
FROM
(SELECT Name,ROW_NUMBER() OVER(ORDER BY column_id) AS 'RowNum'
FROM tempdb.sys.Columns
WHERE Object_ID = OBJECT_ID('tempdb..#tbl')
) AS A WHERE A.RowNum>1
SET @rows=STUFF(@rows,1,1,'')
SET @query='SELECT *
from #tbl
unpivot (value for name in ('+@rows+')) up
pivot (max(value) for color in ('+@Cols+')) p'
EXEC (@query)