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

Hvordan pivoterer man ukendt antal kolonner og ingen aggregater i SQL Server?

Mens M.Alis svar vil give dig resultatet, da du bruger SQL Server 2012, ville jeg fjerne pivot name og address kolonner lidt anderledes for at få det endelige resultat.

Da du bruger SQL Server 2012, kan du bruge CROSS APPLY med VALUES for at frigøre disse flere kolonner i flere rækker. Men før du gør det, ville jeg bruge row_number() for at få det samlede antal nye kolonner, du vil have.

Koden til at "UNPIVOT" dataene ved hjælp af CROSS APPLY ser sådan ud:

select d.loanid, 
  col = c.col + cast(seq as varchar(10)),
  c.value
from
(
  select loanid, name, address,
    row_number() over(partition by loanid
                      order by loanid) seq
  from yourtable
) d
cross apply
(
  values
    ('name', name),
    ('address', address)
) c(col, value);
 

Se SQL Fiddle with Demo. Dette vil få dine data til et format, der ligner:

| LOANID | COL | VALUE | |--------|----------|----------| | 1 | name1 | John | | 1 | address1 | New York | | 1 | name2 | Carl | | 1 | address2 | New York | | 1 | name3 | Henry | | 1 | address3 | Boston |

Du har nu en enkelt kolonne COL med alle dine nye kolonnenavne og de tilknyttede værdier er også i en enkelt kolonne. De nye kolonnenavne har nu et nummer i slutningen (1, 2, 3 osv.) baseret på hvor mange samlede poster du har pr. loanid . Nu kan du anvende PIVOT:

select loanid,
  name1, address1, name2, address2,
  name3, address3
from
(
  select d.loanid, 
    col = c.col + cast(seq as varchar(10)),
    c.value
  from
  (
    select loanid, name, address,
      row_number() over(partition by loanid
                        order by loanid) seq
    from yourtable
  ) d
  cross apply
  (
    values
      ('name', name),
      ('address', address)
  ) c(col, value)
) src
pivot
(
  max(value)
  for col in (name1, address1, name2, address2,
              name3, address3)
) piv;
 

Se SQL Fiddle with Demo. Endelig hvis du ikke ved hvor mange par Name og Address du har, så kan du bruge dynamisk SQL:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(col+cast(seq as varchar(10))) 
                    from 
                    (
                      select row_number() over(partition by loanid
                                                order by loanid) seq
                      from yourtable
                    ) d
                    cross apply
                    (
                      select 'Name', 1 union all
                      select 'Address', 2
                    ) c (col, so)
                    group by seq, col, so
                    order by seq, so
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT loanid,' + @cols + ' 
            from 
            (
              select d.loanid, 
                col = c.col + cast(seq as varchar(10)),
                c.value
              from
              (
                select loanid, name, address,
                  row_number() over(partition by loanid
                                    order by loanid) seq
                from yourtable
              ) d
              cross apply
              (
                values
                  (''name'', name),
                  (''address'', address)
              ) c(col, value)
            ) x
            pivot 
            (
                max(value)
                for col in (' + @cols + ')
            ) p '

exec sp_executesql @query;
 

Se SQL Fiddle with Demo. Begge versioner giver et resultat:

| LOANID | NAME1 | ADDRESS1 | NAME2 | ADDRESS2 | NAME3 | ADDRESS3 | |--------|--------|----------|--------|----------|--------|----------| | 1 | John | New York | Carl | New York | Henry | Boston | | 2 | Robert | Chicago | (null) | (null) | (null) | (null) | | 3 | Joanne | LA | Chris | LA | (null) | (null) |

  1. Hvordan kan jeg bruge forberedte erklæringer i CodeIgniter

  2. Sådan laver du dynamiske postgres-forberedte erklæringer i PHP

  3. Logon-triggere i SQL Server

  4. Hvor er mit ugyldige tegn (ORA-00911)