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

Jak pivotovat neznámý počet sloupců a žádný agregát na SQL Server?

Zatímco odpověď M.Ali vám poskytne výsledek, protože používáte SQL Server 2012, zrušil bych otočení name a address sloupce se mírně liší, abyste získali konečný výsledek.

Protože používáte SQL Server 2012, můžete použít CROSS APPLY s VALUES k rozbalení těchto více sloupců do více řádků. Ale než to uděláte, použil bych row_number() získat celkový počet nových sloupců, které budete mít.

Kód pro "UNPIVOT" data pomocí CROSS APPLY vypadá takto:

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

Viz SQL Fiddle s ukázkou. Tím se vaše data přenesou do formátu podobného:

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

Nyní máte jeden sloupec COL všechny vaše nové názvy sloupců a související hodnoty jsou také v jednom sloupci. Nové názvy sloupců mají nyní na konci číslo (1, 2, 3 atd.) podle celkového počtu položek, které máte na loanid . Nyní můžete použít 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;

Viz SQL Fiddle s ukázkou. Konečně, pokud nevíte, kolik párů Name a Address budete mít, pak můžete použít dynamické 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;

Viz SQL Fiddle s ukázkou. Obě verze dávají výsledek:

| 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. Jak zakázat spouštění v Oracle SQL Developer?

  2. Existuje způsob, jak získat číslo řádku v Mysql jako rownum v oracle

  3. Najděte záznamy SQL obsahující podobné řetězce

  4. Aritmetika sloupce data v dotazu PostgreSQL