sql >> Databáze >  >> RDS >> Sqlserver

Jak převést hodnoty řádků na sloupce s počtem dynamických sloupců?

Můj návrh, kdykoli pracujete s PIVOTem, je vždy nejprve napsat dotaz s pevně zakódovanými hodnotami, poté můžete dotaz snadno převést na dynamické řešení.

Protože budete mít více hodnot columnC které budou převedeny na sloupce, pak se musíte podívat na pomocí row_number() funkce okna pro generování jedinečné sekvence pro každý columnc na základě hodnot columnA a columnB .

Výchozím bodem pro váš dotaz bude:

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

Viz Demo. Tento dotaz vygeneruje seznam názvů nových sloupců SampleTitle1 atd.:

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

Poté můžete použít pivot na columnC s novými názvy sloupců uvedenými v 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;

Viz SQL Fiddle with Demo.

Jakmile budete mít správnou logiku, můžete data převést na dynamický SQL. Klíčem je zde vygenerování seznamu nových názvů sloupců. Obvykle používám FOR XML PATH pro toto podobné:

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,'')

Viz Demo. Jakmile budete mít seznam názvů sloupců, vygenerujete svůj řetězec SQL, který chcete spustit, úplný kód bude:

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;

Viz SQL Fiddle s ukázkou. Výsledkem je:

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



  1. Počítat kumulativní součet v Postgresql

  2. Spuštění MariaDB v nastavení hybridního cloudu

  3. Náhled dokumentů ve formuláři Microsoft Access

  4. Jak odstranit heslo z databáze v Accessu 2016