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

SQL Server:Pivot с потребителски имена на колони

Има няколко начина, по които можете да направите това.

Ако имате известен брой въпроси/отговори, можете да използвате row_number() заедно с агрегатна функция и CASE израз:

изберете id, max(случай, когато rn =1, след това край на въпроса) question1, max(случай, когато rn =1, тогава край на отговора) answer1, max(случай, когато rn =2, след това край на въпроса) question2, max( случай, когато rn =2, тогава край на отговора) answer2, max(случай, когато rn =3, тогава край на въпроса) question3, max(случай, когато rn =3, тогава край на отговора) answer3from( изберете id, въпрос, отговор, row_number() over(partition) по id ред по id, въпрос) rn от yt) srcgroup по id; 

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

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

Основният синтаксис за UNPIVOT ще бъде:

select id, col+cast(rn as varchar(10)) col, valuefrom( -- когато извършвате unpivot, типовете данни трябва да са еднакви. -- може да се наложи да прехвърлите типовете данни в това заявка изберете id, въпрос, cast(отговор като varchar(500)) отговор, row_number() над(дял по id ред по id, въпрос) rn от yt) srcunpivot(стойност за col in (въпрос, отговор)) unpiv; 

Вижте Демо . Това дава резултат:

<предварителен код>| ID | COL | СТОЙНОСТ |------------------------------------------------ --------------| 4482515 | въпрос1 | Бих искал да бъда информиран по пощата. || 4482515 | отговор1 | Не || 4482515 | въпрос2 | Планирате да закупите? || 4482515 | отговор2 | Над 12 месеца || 4482515 | въпрос3 | Текст на тестовия въпрос || 4482515 | отговор3 | някакъв отговор |

Както можете да видите, добавих row_number() стойност към първоначалната подзаявка, за да можете да свържете всеки отговор с въпроса. След като това бъде отменено, тогава можете да завъртите резултата върху новите имена на колони с въпроса /отговор със стойността на конкатенирания номер на ред. Кодът със синтаксиса PIVOT ще бъде:

изберете id, question1, answer1, question2, answer2, question3, answer3from( select id, col+cast(rn as varchar(10)) col, value from ( -- когато извършвате unpivot, типовете данни имат да бъдат същите. - може да се наложи да прехвърлите типовете данни в тази заявка select id, question, cast(answer as varchar(500)) answer, row_number() over(partition by id order by id, question) rn from yt ) src unpivot ( стойност за колона в (въпрос, отговор) ) unpiv) dpivot (макс. (стойност) за колона в (въпрос1, отговор1, въпрос2, отговор2, въпрос3, отговор3)) piv; 

Вижте SQL Fiddle с демонстрация . Сега във вашата ситуация вие заявихте, че ще имате динамичен брой въпроси/отговори. Ако случаят е такъв, тогава ще трябва да използвате динамичен SQL, за да получите резултата:

DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX)select @cols =STUFF((SELECT ',' + QUOTENAME(c.col+cast(rn as varchar(10))) from ( select row_number() over(partition by id order by id, question) rn from yt ) d cross apply ( select 'question' col, 1 sort union all select 'answer', 2 ) c group by col, rn, sort ред по rn, сортиране ЗА XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')set @query ='SELECT id, ' + @cols + ' from ( select id, col+cast(rn as varchar(10)) col, value from ( -- когато извършвате unpivot, типовете данни трябва да са еднакви. -- може да се наложи да прехвърлите типовете данни в тази заявка select id, question, cast(answer as varchar(500)) answer, row_number() over(partition by id order by id, question) rn from yt ) src unpivot ( value for col in (въпрос, отговор) ) unpiv ) d pivot ( max(стойност) for col in (' + @cols + ') ) p 'execute(@query); 

Вижте SQL Fiddle с демонстрация . Те дават резултат:

<предварителен код>| ID | ВЪПРОС1 | ОТГОВОР1 | ВЪПРОС2 | ОТГОВОР2 | ВЪПРОС3 | ОТГОВОР3 |------------------------------------------------ -------------------------------------------------- ----------------------------------| 4482515 | Бих искал да бъда информиран по пощата. | Не | Планирате да закупите? | Над 12 месеца | Текст на тестовия въпрос | някакъв отговор |


  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 HierarchyID в дълбочина

  2. Преброяване на редове за всички таблици наведнъж

  3. Оптимизация на SQL заявки

  4. Как мога да вляза и да намеря най-скъпите заявки?

  5. Изчисляване на текущото общо с клауза OVER и клауза PARTITION BY в SQL Server