sql >> Database >  >> RDS >> Sqlserver

Hoe een onbekend aantal kolommen te draaien en geen aggregaat in SQL Server?

Hoewel het antwoord van M.Ali u het resultaat zal opleveren, zou ik, aangezien u SQL Server 2012 gebruikt, de draai van de name ongedaan maken en address kolommen iets anders om het uiteindelijke resultaat te krijgen.

Aangezien u SQL Server 2012 gebruikt, kunt u CROSS APPLY . gebruiken met VALUES om de draaiing van deze meerdere kolommen in meerdere rijen ongedaan te maken. Maar voordat je dat doet, zou ik row_number() . gebruiken om het totale aantal nieuwe kolommen te krijgen dat u zult hebben.

De code om de gegevens "UNPIVOT" te maken met CROSS APPLY ziet er als volgt uit:

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);

Zie SQL Fiddle met demo. Dit zal uw gegevens in een formaat krijgen dat lijkt op:

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

U heeft nu een enkele kolom COL met al uw nieuwe kolomnamen en de bijbehorende waarden staan ​​ook in één kolom. De nieuwe kolomnamen hebben nu een nummer aan het einde (1, 2, 3, enz.) op basis van het totale aantal vermeldingen dat u per loanid hebt. . Nu kunt u PIVOT toepassen:

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;

Zie SQL Fiddle met demo. Tot slot, als u niet weet hoeveel paren Name en Address je hebt dan kun je dynamische SQL gebruiken:

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;

Zie SQL Fiddle met demo. Beide versies geven een resultaat:

| 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. Meerdere kolommen bijwerken in MySQL

  2. Hoe voeg ik een tekenreeks toe met een automatische verhogingswaarde in SQL Server?

  3. Hoe speciale tekens zoals &in te voeren in de Oracle-database?

  4. Gegevens exporteren naar Excel vanuit Oracle Table met behulp van PL SQL