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

Лесен начин за транспониране на колони и редове в SQL?

Има няколко начина, по които можете да трансформирате тези данни. В оригиналната си публикация сте посочили, че PIVOT изглежда твърде сложен за този сценарий, но може да се приложи много лесно с помощта на UNPIVOT и PIVOT функции в SQL Server.

Въпреки това, ако нямате достъп до тези функции, това може да бъде възпроизведено с помощта на UNION ALL до UNPIVOT и след това агрегатна функция с CASE изявление към PIVOT :

Създаване на таблица:

СЪЗДАЙТЕ ТАБЛИЦА yourTable([color] varchar(5), [Paul] int, [John] int, [Tim] int, [Eric] int);INSERT INTO yourTable ([color], [Paul] , [Джон], [Тим], [Ерик])ЦЕННОСТИ („Червено“, 1, 5, 1, 3), („Зелено“, 8, 4, 3, 5), („Синьо“, 2, 2 , 9, 1); 

Union All, Aggregate и CASE версия:

изберете име, сума(случай, когато цвят ='Червен', след това стойност друго 0 край) Червен, сума (случай, когато цвят ='Зелено', след това стойност друга 0 край) Зелен, сума (случай, когато цвят =' Blue“ след това стойност else 0 end) Bluefrom( изберете цвят, Paul value, „Paul“ име от yourTable union, всички изберете цвят, John value, „John“ name от yourTable union, всички изберете цвят, Tim value, „Tim“ име от вашата таблица union all select color, Eric value, 'Eric' name from yourTable) srcgroup by name 

Вижте SQL Fiddle с демонстрация

UNION ALL изпълнява UNPIVOT на данните чрез трансформиране на колоните Пол, Джон, Тим, Ерик на отделни редове. След това прилагате агрегатната функция sum() с случай оператор, за да получите новите колони за всеки color .

Отмяна на завъртане и завъртане на статична версия:

И двата UNPIVOT и PIVOT функциите в SQL сървъра правят тази трансформация много по-лесна. Ако знаете всички стойности, които искате да трансформирате, можете да ги кодирате в статична версия, за да получите резултата:

изберете име, [червено], [зелено], [синьо]от( изберете цвят, име, стойност от вашата таблица unpivot (стойност за име в (Пол, Джон, Тим, Ерик) ) unpiv) srcpivot( sum(value) за цвят в ([Red], [Green], [Blue])) piv 

Вижте SQL Fiddle с демонстрация

Вътрешната заявка с UNPIVOT изпълнява същата функция като UNION ALL . Той взема списъка с колони и го превръща в редове, PIVOT след това извършва окончателната трансформация в колони.

Динамична осигурена версия:

Ако имате неизвестен брой колони (Пол, Джон, Тим, Ерик във вашия пример) и след това неизвестен брой цветове за трансформиране, можете да използвате динамичен sql, за да генерирате списъка за UNPIVOT и след това PIVOT :

ДЕКЛАРИРАНЕ @colsUnpivot КАТО NVARCHAR(MAX), @query КАТО NVARCHAR(MAX), @colsPivot като NVARCHAR(MAX)select @colsUnpivot =stuff((select ','+quotename(C.name) от sys) .columns като C, където C.object_id =object_id('вашата таблица') и C.name <> 'color' за xml path('')), 1, 1, '')select @colsPivot =STUFF((SELECT ', ' + цитат(цвят) от вашата таблица t ЗА XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')set @query ='изберете име, ' [email protected]+' от ( изберете цвят, име, стойност от вашата таблица unpivot (стойност за име в ('[email protected]+')) unpiv) src опорна точка (сума(стойност) за цвят в ('example@sqldat. com+') ) piv'exec(@query) 

Вижте SQL Fiddle с демонстрация

Динамичната версия отправя заявки към вашата таблица и след това sys.columns таблица за генериране на списък с елементи за UNPIVOT и PIVOT . След това това се добавя към низ на заявка, който трябва да бъде изпълнен. Плюсът на динамичната версия е, че имате променящ се списък с цветове и/или имена това ще генерира списъка по време на изпълнение.

И трите заявки ще дадат един и същ резултат:

<предварителен код>| ИМЕ | ЧЕРВЕНО | ЗЕЛЕНО | СИН |----------------------------| Ерик | 3 | 5 | 1 || Джон | 5 | 4 | 2 || Павел | 1 | 8 | 2 || Тим | 1 | 3 | 9 |

  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. SqlParameter не позволява име на таблица - други опции без атака на sql инжекция?

  3. GROUP BY за комбиниране/свързване на колона

  4. Използвайте SET TEXTSIZE, за да ограничите връщаните данни за всеки ред в SQL Server

  5. Какво означава времеви печат в T-Sql в C#?