Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Динамично развъртане и разделяне на колони SQL Server 2012

Просто трябва да разделите колоните, след като направите UNPIVOT нещо подобно:

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 MetricsFROM Unpivoted; 

След това, разбира се, трябва да го направите динамично, за да избегнете ръчното изброяване на колоните и да го направите динамично:

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 ='Региони ' И COLUMN_NAME <> 'Регион' И COLUMN_NAME <> 'LOB' ЗА 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%'' СЛЕД ТОВА ЗАМЕНЕТЕ(стойност,''GWP'', '''') WHEN стойност КАТО ''LR%'' THEN REPLACE(стойност,''LR '', '''') END AS INT) AS Година, CASE WHEN стойност КАТО ''GWP%'' THEN '' GWP'' WHEN стойност КАТО ''LR%'' THEN ''LR'' END AS Metrics FROM Unpivoted';EXECUTE(@query); 

Това трябва да работи добре, ако приемем, че:

  • Всички колони [GWP 2013] , [GWP 2014] , [LR 2013] , [LR 2014] , [GWP 2015], [LR 2015], ... и т.н. са в същия формат (GWP или LR, след това интервал, след това годината и
  • Всички колони са от един и същи тип данни int или десетичен, ако типовете данни не са еднакви, трябва да прехвърлите всички в един тип данни, преди да направите unpivot в противен случай ще получите грешка.

  • Демонстрация на SQL Fiddle

Това ще ви даде:

<предварителен код>| регион | лоб | колони | Година | Показатели ||--------|---------|----------|------|---------| | Север | Работници | 38902.5 | 2013 | GWP || Север | Работници | 37972404 | 2014 | GWP || Север | Работници | 70 | 2015 | GWP || Север | Работници | 89 | 2013 | LR || Север | Работници | 82 | 2014 | LR || Север | Работници | 80 | 2015 | LR |

Актуализация:

Използвах FOR XML PATH('') .. за да свържете целия списък със стойности в един низ, това е работа в SQL Server. Стойността на @cols ще бъде низът:[GWP 2013], [GWP 2014], ... .

Ако типът данни на вашите полета е различен, трябва да направите преобразуването на всички колони, които ще бъдат деактивирани в заявката за закрепване, преди да извършите UNPVOT като това:

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], ... и т.н. FROM Regions ) AS t UNPIVOT (колони ЗА стойност IN('+ @cols + ') ) AS u ) ИЗБЕРЕТЕ регион, лоб, колони, CAST(CASE WHEN стойност КАТО ''GWP%'' THEN REPLACE(стойност,''GWP '', '''') WHEN стойност LIKE ''LR%'' THEN REPLACE(стойност,''LR ' ', '''') END AS INT) AS Година, C ASE WHEN стойност КАТО ''GWP%'' THEN ''GWP'' WHEN стойност КАТО ''LR%'' THEN ''LR'' END AS Metrics FROM Unpivoted'; 

Ако ви е било трудно да напишете кастинга за всички колони ръчно, можете да го генерирате динамично и вместо това да го добавите, например:

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, ''); 

След това в динамичната заявка добавете тази стойност към нея:

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 стойност LIKE ''LR %'' THEN REPLACE(value,''LR '', '''') END AS INT) AS Year, CASE WHEN value LIKE ''GWP%'' THEN ''GWP'' WHEN value LIKE ''LR%' ' ТОГАВА ''LR'' END AS Metrics FROM Unpivoted'; EXECUTE(@query); 



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да получите първия и последния ден от предходния месец (с времеви печат) в SQL Server

  2. Как да изброите остарелите функции в екземпляр на SQL сървър с помощта на T-SQL

  3. Как да предадете стойност на име на колона като SQL аргумент с помощта на контейнери

  4. Създаване на запомнена процедура чрез C#

  5. Функцията YEARFRAC на SQL Server не работи