Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak przekonwertować wartości wierszy na kolumny z dynamiczną liczbą kolumn?

Moja sugestia, gdy pracujesz z PIVOT, to zawsze najpierw pisać zapytanie z wartościami zakodowanymi na stałe, a następnie możesz łatwo przekonwertować zapytanie na dynamiczne rozwiązanie.

Ponieważ będziesz mieć wiele wartości columnC które zostaną przekonwertowane na kolumny, musisz przyjrzeć się za pomocą row_number() funkcja okienkowa do generowania unikalnej sekwencji dla każdej columnc na podstawie wartości columnA i columnB .

Punktem wyjścia dla Twojego zapytania będzie:

select [ColumnA],
  [ColumnB],
  [ColumnC],
  'SampleTitle'+
  cast(row_number() over(partition by columna, columnb
                          order by columnc) as varchar(10)) seq
from DataSource;

Zobacz Demo. To zapytanie wygeneruje listę nowych nazw kolumn SampleTitle1 itp:

| COLUMNA | COLUMNB | COLUMNC |          SEQ |
|---------|---------|---------|--------------|
|    5060 |    1006 |  100118 | SampleTitle1 |
|    5060 |    1006 |  100119 | SampleTitle2 |
|    5060 |    1006 |  100120 | SampleTitle3 |

Następnie możesz zastosować element przestawny na columnC z nowymi nazwami kolumn wymienionymi w seq :

select columnA, columnB, 
  SampleTitle1, SampleTitle2, SampleTitle3
from
(
   select [ColumnA],
    [ColumnB],
    [ColumnC],
    'SampleTitle'+
      cast(row_number() over(partition by columna, columnb
                              order by columnc) as varchar(10)) seq
   from DataSource
) d
pivot
(
  max(columnc)
  for seq in (SampleTitle1, SampleTitle2, SampleTitle3)
) piv;

Zobacz SQL Fiddle z wersją demonstracyjną.

Gdy masz poprawną logikę, możesz przekonwertować dane na dynamiczny SQL. Kluczem jest tutaj wygenerowanie listy nowych nazw kolumn. Zwykle używam FOR XML PATH dla tego podobnego do:

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

Zobacz Demo. Gdy masz już listę nazw kolumn, wygenerujesz ciąg sql do wykonania, pełny kod będzie wyglądał następująco:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(seq) 
                    from
                    (
                      select 'SampleTitle'+
                        cast(row_number() over(partition by columna, columnb
                                                order by columnc) as varchar(10)) seq
                      from DataSource
                    ) d
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT columnA, ColumnB,' + @cols + ' 
             from 
             (
               select [ColumnA],
                [ColumnB],
                [ColumnC],
                ''SampleTitle''+
                  cast(row_number() over(partition by columna, columnb
                                          order by columnc) as varchar(10)) seq
               from DataSource
            ) x
            pivot 
            (
                max(columnc)
                for seq in (' + @cols + ')
            ) p '

execute sp_executesql @query;

Zobacz SQL Fiddle z demonstracją. Dają wynik:

| COLUMNA | COLUMNB | SAMPLETITLE1 | SAMPLETITLE2 | SAMPLETITLE3 |
|---------|---------|--------------|--------------|--------------|
|    5060 |    1006 |       100118 |       100119 |       100120 |
|    5060 |    1007 |       100121 |       100122 |       (null) |
|    5060 |    1012 |       100123 |       (null) |       (null) |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak tworzyć widoki zmaterializowane w SQL Server?

  2. Przykład wstawiania SQL Server

  3. Tabele SQL Server:jaka jest różnica między @, # i ##?

  4. Dziennik transakcji SQL Server — część 1

  5. 4 sposoby na uzyskanie listy harmonogramów w programie SQL Server Agent (T-SQL)