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

Transpozycja wierszy i kolumn bez agregatu

Jeśli zamierzasz zastosować PIVOT funkcji, będziesz musiał użyć funkcji agregującej, aby uzyskać wynik, ale będziesz także chciał użyć funkcji okienkowej, takiej jak row_number() aby wygenerować unikalną sekwencję dla każdego kontaktu na koncie.

Najpierw wyślesz zapytanie o swoje dane w sposób podobny do:

select account, contact,
  'contact'
    + cast(row_number() over(partition by account
                              order by contact) as varchar(10)) seq
from yourtable

Zobacz SQL Fiddle z wersją demonstracyjną. Spowoduje to utworzenie nowej kolumny z unikalną sekwencją:

| ACCOUNT |   CONTACT |      SEQ |
|---------|-----------|----------|
|       1 | 324324324 | contact1 |
|       1 | 674323234 | contact2 |

Jeśli masz ograniczoną liczbę kolumn, możesz na stałe zakodować zapytanie:

select account,
  contact1, contact2, contact3, contact4
from 
(
  select account, contact,
    'contact'
      + cast(row_number() over(partition by account
                                order by contact) as varchar(10)) seq
  from yourtable
) d
pivot
(
  max(contact)
  for seq in (contact1, contact2, contact3, contact4)
) piv;

Zobacz SQL Fiddle z demonstracją

Jeśli masz nieznaną liczbę kolumn, będziesz musiał użyć dynamicznego SQL:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(seq) 
                    from
                    (
                      select 'contact'
                              + cast(row_number() over(partition by account
                                                        order by contact) as varchar(10)) seq
                      from yourtable
                    ) d
                    group by seq
                    order by seq
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT account, ' + @cols + ' 
            from 
            (
                select account, contact,
                  ''contact''
                    + cast(row_number() over(partition by account
                                              order by contact) as varchar(10)) seq
                from yourtable
            ) x
            pivot 
            (
                max(contact)
                for seq in (' + @cols + ')
            ) p '

execute sp_executesql @query;

Zobacz SQL Fiddle z wersją demonstracyjną. Oba dadzą wynik:

| ACCOUNT |  CONTACT1 |  CONTACT2 |  CONTACT3 |  CONTACT4 |
|---------|-----------|-----------|-----------|-----------|
|       1 | 324324324 | 674323234 |    (null) |    (null) |
|       2 | 433243443 | 833343432 |    (null) |    (null) |
|       3 | 787655455 |    (null) |    (null) |    (null) |
|       4 | 455435435 | 754327545 |    (null) |    (null) |
|       5 | 432432432 | 432433242 | 432455553 | 543544355 |


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wstawianie listy<> do tabeli SQL Server

  2. Jak filtrować obiekty w SQL Server Management Studio (SSMS) — samouczek SQL Server / TSQL, część 19

  3. Kopia zapasowa SQL Server 2017 -1

  4. Naruszenie ograniczenia UNIQUE KEY na INSERT WHERE COUNT(*) =0 w SQL Server 2005

  5. Jak sprawdzić, czy baza danych SQL jest uszkodzona — rozwiązanie do naprawy pliku MDF