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

Pivot flere kolonner baseret på én kolonne i SQL Server

Da du bruger SQL Server, er der flere forskellige måder, hvorpå du kan konvertere rækkerne til kolonner. Du kan bruge en aggregeret funktion med et CASE-udtryk:

select empid,
  max(case when empindex = 1 then empstate end) empState1,
  max(case when empindex = 1 then empStDate end) empStDate1,
  max(case when empindex = 1 then empEndDate end) empEndDate1,
  max(case when empindex = 2 then empstate end) empState2,
  max(case when empindex = 2 then empStDate end) empStDate2,
  max(case when empindex = 2 then empEndDate end) empEndDate2
from sourcetbl
group by empid;
 

Se SQL Fiddle with Demo.

Hvis du vil bruge PIVOT-funktionen til at få resultatet, så vil jeg anbefale først at deaktivere kolonnerne empState , empStDate og empEndDate så du har flere rækker først. Du kan bruge UNPIVOT-funktionen eller CROSS APPLY til at konvertere de data, som koden bliver:

select empid, col+cast(empindex as varchar(10)) col,  value
from sourcetbl
cross apply
(
  select 'empstate', empstate union all
  select 'empstdate', convert(varchar(10), empstdate, 120) union all
  select 'empenddate', convert(varchar(10), empenddate, 120)
) c (col, value);
 

Se Demo. Når dataene er unpivoted, kan du anvende PIVOT-funktionen, så den endelige kode bliver:

select empid,
  empState1, empStDate1, empEndDate1,
  empState2, empStDate2, empEndDate2
from 
(
  select empid, col+cast(empindex as varchar(10)) col,  value
  from sourcetbl
  cross apply
  (
    select 'empstate', empstate union all
    select 'empstdate', convert(varchar(10), empstdate, 120) union all
    select 'empenddate', convert(varchar(10), empenddate, 120)
  ) c (col, value)
) d
pivot
(
  max(value)
  for col in (empState1, empStDate1, empEndDate1,
              empState2, empStDate2, empEndDate2)
) piv;
 

Se SQL Fiddle with Demo.

Ovenstående versioner vil fungere godt, hvis du har et begrænset antal empindex , men hvis ikke, kan du bruge dynamisk SQL:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(col+cast(empindex as varchar(10))) 
                    from SourceTbl
                    cross apply
                    (
                      select 'empstate', 1 union all
                      select 'empstdate', 2 union all
                      select 'empenddate', 3
                    ) c (col, so)
                    group by col, so, empindex
                    order by empindex, so
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT empid,' + @cols + ' 
            from 
            (
                select empid, col+cast(empindex as varchar(10)) col,  value
                from sourcetbl
                cross apply
                (
                  select ''empstate'', empstate union all
                  select ''empstdate'', convert(varchar(10), empstdate, 120) union all
                  select ''empenddate'', convert(varchar(10), empenddate, 120)
                ) c (col, value)
            ) x
            pivot 
            (
                max(value)
                for col in (' + @cols + ')
            ) p '

execute sp_executesql @query;
 

Se SQL Fiddle with Demo

Du kan bruge disse forespørgsler til at INDSÆTTE I din DestTbl , eller i stedet for at gemme dataene i dette format, har du nu en forespørgsel for at få det ønskede resultat.

Disse forespørgsler placerer dataene i formatet:

| EMPID | EMPSTATE1 | EMPSTDATE1 | EMPENDDATE1 | EMPSTATE2 | EMPSTDATE2 | EMPENDDATE2 | --------------------------------------------------------------------------------------- | 10 | AL | 2012-01-01 | 2012-12-01 | FL | 2012-02-01 | 2013-02-01 | | 15 | FL | 2012-03-20 | 2099-01-01 | (null) | (null) | (null) |

  1. Hvordan tilføjes kolonne i tabel i SQL?

  2. Sådan fungerer TIME_FORMAT() i MariaDB

  3. Implementering af SQL Server Performance Indicator for forespørgsler, lagrede procedurer og triggere

  4. Kombinerer styrken af ​​SQL og proceduremæssige erklæringer med MariaDBs Oracle-kompatibilitetstilstand