Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak przestawić nieznaną liczbę kolumn i brak agregacji w SQL Server?

Podczas gdy odpowiedź M.Ali da ci wynik, ponieważ używasz SQL Server 2012, odwróciłbym name i address kolumny nieco się różnią, aby uzyskać ostateczny wynik.

Ponieważ używasz SQL Server 2012, możesz użyć CROSS APPLY z VALUES aby przestawić te wiele kolumn na wiele wierszy. Ale zanim to zrobisz, użyję row_number() aby uzyskać całkowitą liczbę nowych kolumn, które będziesz mieć.

Kod do „UNPIVOT” danych za pomocą CROSS APPLY wygląda następująco:

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

Zobacz SQL Fiddle z wersją demonstracyjną. Spowoduje to uzyskanie danych w formacie podobnym do:

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

Masz teraz jedną kolumnę COL wszystkie nowe nazwy kolumn i powiązane wartości również znajdują się w jednej kolumnie. Nowe nazwy kolumn mają teraz numer na końcu (1, 2, 3, itd.) w oparciu o liczbę wszystkich wpisów na loanid . Teraz możesz zastosować 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;

Zobacz SQL Fiddle z demonstracją. Wreszcie, jeśli nie wiesz, ile par Name i Address będziesz miał wtedy możesz użyć dynamicznego 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;

Zobacz SQL Fiddle z demonstracją. Obie wersje dają wynik:

| 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak tworzyć niestandardowe skróty w SQL Server Management Studio (SSMS) — samouczek SQL Server / TSQL część 10

  2. Jak zastąpić NULL inną wartością w SQL Server – ISNULL()

  3. Moje zapytanie Wybierz SUMA zwraca wartość null. Powinien zwrócić 0

  4. Podziel zakres dat na jeden wiersz na miesiąc na serwerze sql

  5. Korzystanie z alertów i operatorów w SQL Server