行列转化/横转竖这个在日常的工作中中算是比较常见的了,但长时间的不使用也难免忘记,这里做下备忘。
场景Ⅰ-看图
实现没有什么难度,直接上代码:
DECLARE @t TABLE(col VARCHAR(50)) INSERT INTO @t SELECT 'A' UNION ALL SELECT 'B' UNION ALL SELECT 'C' UNION ALL SELECT 'D' UNION ALL SELECT 'E' UNION ALL SELECT 'F' UNION ALL SELECT 'G' UNION ALL SELECT 'H' UNION ALL SELECT 'I' UNION ALL SELECT 'J' UNION ALL SELECT 'K'; DECLARE @str VARCHAR(2000) SELECT @str=ISNULL(@str+',','')+''+col+'='+ ''''+col+'''' FROM @t SET @str=N'select '+@str EXEC(@str) --需要物理表,使用国标表变量会报错,具体原因不详 DECLARE @str VARCHAR(8000) SELECT @str=ISNULL(@str+',','')+'['+col+']' FROM @t GROUP BY col SET @str='SELECT * FROM @t PIVOT(MAX(col) FOR quaters in('+@str+'))a' --PRINT @str EXEC(@str)
场景Ⅱ-进阶上图
这个是不是比场景Ⅰ中的有意思的多,废话不多说,上代码:
DECLARE @MyTest TABLE(product varchar(50),[200301] int,[200302] int,[200303] int ) INSERT INTO @MyTest SELECT '干果',1000,1200,1800 UNION ALL SELECT '海鲜',2200,2500,2800 UNION ALL SELECT '粮油',3600,3800,4200 SELECT * FROM @MyTest DECLARE @prod1 VARCHAR(5000),@prod2 VARCHAR(5000),@prod3 VARCHAR(5000) SELECT @prod1=ISNULL(@prod1+',','')+ product+'='''+ CAST([200301] AS VARCHAR(50))+'''', @prod2=ISNULL(@prod2+',','') + product+'='''+ CAST([200302] AS VARCHAR(50))+'''', @prod3=ISNULL(@prod3+',','')+ product+'='''+ CAST([200303] AS VARCHAR(50))+'''' FROM @MyTest SET @prod1='Select 日期=''200301'','+@prod1+' UNION ALL Select 日期=''200302'','+@prod2+' UNION ALL Select 日期=''200303'','+@prod3 EXEC(@prod1)
当然上面的如果看着不熟悉,下面的代码一定不会陌生:
CREATE TABLE #MyTC(YEARs INT, quaters INT,amount DECIMAL(18,2)) INSERT INTO #MyTC SELECT 1990,1,1.1 UNION ALL SELECT 1990,2,1.2 UNION ALL SELECT 1990,3,1.3 UNION ALL SELECT 1990,4,1.4 UNION ALL SELECT 1991,1,2.1 UNION ALL SELECT 1991,2,2.2 UNION ALL SELECT 1991,3,2.3 UNION ALL SELECT 1991,4,2.4 SELECT * FROM #MyTC -- ============================================= --固定式 -- ============================================= SELECT 年份=YEARs, 一季度=MAX(CASE quaters WHEN 1 THEN amount END), 二季度=MAX(CASE quaters WHEN 2 THEN amount END), 三季度=MAX(CASE quaters WHEN 3 THEN amount END), 四季度=MAX(CASE quaters WHEN 4 THEN amount END) FROM #MyTC GROUP BY YEARs -- ============================================= --动态sql -- ============================================= DECLARE @str VARCHAR(8000) SELECT @str=ISNULL(@str+',','')+ '['+CAST(quaters AS varchar)+ '季度]= MAX(CASE quaters WHEN '+CAST(quaters AS varchar)+' THEN amount END)' FROM #MyTC GROUP BY quaters SET @str= 'SELECT 年份=YEARs,'+ @str+ ' from #MyTC GROUP BY YEARs' PRINT @str EXEC(@str) -- ============================================= --固定PIVOT -- ============================================= SELECT * FROM #MyTC PIVOT(MAX(amount) FOR quaters in([1],[2],[3],[4]))a -- ============================================= --动态PIVOT -- ============================================= DECLARE @str VARCHAR(8000) SELECT @str=ISNULL(@str+',','')+QUOTENAME(quaters) FROM #MyTC GROUP BY quaters SET @str='SELECT * FROM #MyTC PIVOT(MAX(amount) FOR quaters in('+@str+'))a' --PRINT @str EXEC(@str)