sql >> Database teknologi >  >> RDS >> Sqlserver

Hvordan konverterer man rækkeværdier til kolonner med dynamiske kolonnetællinger?

Mit forslag, når du arbejder med PIVOT, er altid at skrive forespørgslen først med værdierne hårdkodet, så kan du nemt konvertere forespørgslen til en dynamisk løsning.

Da du kommer til at have flere værdier af columnC der vil blive konverteret til kolonner, så skal du se på at bruge row_number() vinduesfunktion til at generere en unik sekvens for hver kolonne baseret på værdierne for columnA og columnB .

Udgangspunktet for din forespørgsel vil være:

vælg [ColumnA], [ColumnB], [ColumnC], 'SampleTitle'+ cast(row_number() over(partition efter columna, columnb order by columnc) as varchar(10)) seqfrom DataSource; 

Se Demo. Denne forespørgsel genererer listen over nye kolonnenavne SampleTitle1 osv.:

| KOLUMNE | KOLUMNENB | KOLUMNE | SEQ ||--------|--------|--------|--------------------|| 5060 | 1006 | 100118 | SampleTitle1 || 5060 | 1006 | 100119 | SampleTitle2 || 5060 | 1006 | 100120 | SampleTitle3 |

Du kan derefter anvende pivot på columnC med de nye kolonnenavne angivet i seq :

vælg kolonneA, kolonneB, SampleTitle1, SampleTitle2, SampleTitle3from( vælg [ColumnA], [ColumnB], [ColumnC], 'SampleTitle'+ cast(row_number() over(partition efter kolonne, kolonneb orden efter kolonnec) som varchar(10)) seq fra DataSource) dpivot( max(columnc) for seq in (SampleTitle1, SampleTitle2, SampleTitle3)) piv; 

Se SQL Fiddle with Demo.

Når du har den rigtige logik, kan du konvertere dataene til dynamisk SQL. Nøglen her er at generere listen over nye kolonnenavne. Jeg bruger typisk FOR XML PATH for dette svarende til:

vælg STUFF((SELECT distinct ',' + QUOTENAME(seq) from ( vælg 'SampleTitle'+ cast(row_number() over(partition efter columna, columnb order by columnc) as varchar(10)) seq fra DataSource ) d FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') 

Se Demo. Når du har listen over kolonnenavne, vil du generere din sql-streng for at udføre, den fulde kode vil være:

DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX)vælg @cols =TING((SELECT distinct ',' + QUOTENAME(seq) from ( vælg 'SampleTitle'+ cast(row_number( ) over(partition efter kolonne, kolonneb orden efter kolonnec) som varchar(10)) seq fra DataSource ) d FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1, 1,'')set @query ='SELECT columnA, ColumnB,' + @cols + ' from ( vælg [ColumnA], [ColumnB], [ColumnC], ''SampleTitle''+ cast(row_number() over(partition efter kolonne, kolonneb orden efter kolonnec) som varchar(10)) seq fra DataSource ) x pivot (max(kolonne) f eller seq in (' + @cols + ') ) p 'execute sp_executesql @query; 

Se SQL Fiddle with Demo. Disse giver et resultat:

| KOLUMNE | KOLUMNENB | SAMPLETITLE1 | SAMPLETITLE2 | SAMPLETITLE3 ||--------|--------|--------------------|------------ --|--------------------|| 5060 | 1006 | 100118 | 100119 | 100120 || 5060 | 1007 | 100121 | 100122 | (nul) || 5060 | 1012 | 100123 | (nul) | (null) |


  1. SQL Server - parametersniffing

  2. En guide til MySQL Galera Cluster Streaming Replikering:Første del

  3. Hvad er DATALENGTH() i SQL Server?

  4. Sådan får du vist transaktionslogfiler i SQL Server 2008