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

Как да конвертирате стойностите на редовете в колони с динамичен брой колони?

Моето предложение винаги, когато работите с PIVOT, е винаги първо да пишете заявката с твърдо кодирани стойности, след което лесно можете да конвертирате заявката в динамично решение.

Тъй като ще имате множество стойности на columnC които ще бъдат преобразувани в колони, тогава трябва да разгледате с помощта на row_number() функция за създаване на прозорец за генериране на уникална последователност за всяка columnc въз основа на стойностите на columnA и колона B .

Началната точка за вашата заявка ще бъде:

изберете [ColumnA], [ColumnB], [ColumnC], 'SampleTitle'+ cast(row_number() over(partition by columna, columnb ред по columnc) като varchar(10)) seqfr от DataSource; 

Вижте Демо. Тази заявка ще генерира списък с имена на нови колони SampleTitle1 и т.н.:

<предварителен код>| КОЛОНА | КОЛОНА | КОЛОНА | SEQ ||--------|--------|--------|--------------|| 5060 | 1006 | 100118 | SampleTitle1 || 5060 | 1006 | 100119 | SampleTitle2 || 5060 | 1006 | 100120 | SampleTitle3 |

След това можете да приложите централната част на columnC с новите имена на колони, изброени в seq :

изберете columnA, columnB, SampleTitle1, SampleTitle2, SampleTitle3from( изберете [ColumnA], [ColumnB], [ColumnC], 'SampleTitle'+ cast(row_number() over(partition by columna, columnb ред по columnc)) като varchar(10)) seq от DataSource) dpivot( max(columnc) за seq в (SampleTitle1, SampleTitle2, SampleTitle3)) piv; 

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

След като имате правилната логика, можете да конвертирате данните в динамичен SQL. Ключът тук е генерирането на списък с имена на нови колони. Обикновено използвам ЗА XML PATH за това подобно на:

изберете STUFF((SELECT different ',' + QUOTENAME(seq) from ( изберете 'SampleTitle'+ cast(row_number() over(partition by columna, columnb order by columnc) as varchar(10)) seq от DataSource ) d ЗА XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') 

Вижте Демо. След като имате списък с имена на колони, ще генерирате своя sql низ за изпълнение, пълният код ще бъде:

ДЕКЛАРИРАНЕ @cols КАТО NVARCHAR(MAX), @query КАТО NVARCHAR(MAX)изберете @cols =STUFF((ИЗБЕРЕТЕ различен ',' + QUOTENAME(seq) от ( изберете 'SampleTitle'+ cast(row_number( ) over(partition by columna, columnb ред по columnc) като varchar(10)) seq от DataSource ) d FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1, 1,'')set @query ='ИЗБЕРЕТЕ колона A, ColumnB,' + @cols + ' от ( изберете [ColumnA], [ColumnB], [ColumnC], ''SampleTitle''+ cast(row_number() over(partition по columna, columnb ред по columnc) като varchar(10)) seq от DataSource ) x pivot ( max(columnc) f или seq в (' + @cols + ') ) p 'изпълни sp_executesql @query; 

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

<предварителен код>| КОЛОНА | КОЛОНА | SAMPLETITLE1 | SAMPLETITLE2 | SAMPLETITLE3 ||--------|--------|--------------|------------ --|--------------|| 5060 | 1006 | 100118 | 100119 | 100120 || 5060 | 1007 | 100121 | 100122 | (нула) || 5060 | 1012 | 100123 | (нула) | (нула) |


  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 с помощта на T-SQL

  2. Как да ИЗБЕРЕТЕ ОТ съхранената процедура

  3. 3 въпроса за наблюдение на SQL Server, които да зададете при поемане на позиция в DBA

  4. Как работи @@MAX_CONNECTIONS в SQL Server

  5. Node.js и Microsoft SQL Server