2014-01-08 9 views
5

ich die folgenden Daten-SetTransponieren von Zeilen und Spalten ohne Aggregat

Account Contact 

1 324324324 
1 674323234 
2 833343432 
2 433243443 
3 787655455 
4 754327545 
4 455435435 
5 543544355 
5 432455553 
5 432433242 
5 432432432 

Ich möchte wie folgt ausgegeben haben:

Account Contact1 Contact2 Contact3 Contact4 

1 324324324 674323234  
2 833343432 433243443  
3 787655455   
4 754327545 455435435  
5 543544355 432455553 432433242 432432432 

Das Problem ist auch, dass ich ein nicht fixiertes Menge von Konten & unfixierte Anzahl von Kontakten

Antwort

9

Wenn Sie die PIVOT Funktion anwenden möchten, müssen Sie eine Aggregatfunktion verwenden, um das Ergebnis zu erhalten, aber Sie werden a Außerdem möchten Sie eine Fensterfunktion wie row_number() verwenden, um eine eindeutige Sequenz für jeden Kontakt im Konto zu generieren.

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

Siehe SQL Fiddle with Demo:

Als erstes müssen Sie Ihre Daten ähnlich abzufragen. Dadurch wird eine neue Spalte mit der einzigartigen Sequenz erstellen:

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

Wenn Sie eine begrenzte Anzahl von Spalten haben, dann könnten Sie schwer Code Anfrage:

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; 

Siehe SQL Fiddle with Demo

Wenn Wenn Sie eine unbekannte Anzahl von Spalten haben, müssen Sie dynamisches SQL verwenden:

Siehe SQL Fiddle with Demo. Beide geben Ihnen ein Ergebnis von:

| 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 | 
2

Nur eine etwas andere Art und Weise die dynamische PIVOT zu generieren:

DECLARE @c INT; 

SELECT TOP 1 @c = COUNT(*) 
    FROM dbo.YourTable 
    GROUP BY Account 
    ORDER BY COUNT(*) DESC; 

DECLARE @dc1 NVARCHAR(MAX) = N'', @dc2 NVARCHAR(MAX) = N'', @sql NVARCHAR(MAX); 

SELECT @dc1 += ',Contact' + RTRIM(i), @dc2 += ',[Contact' + RTRIM(i) + ']' 
    FROM (SELECT TOP (@c) i = number + 1 
    FROM master.dbo.spt_values WHERE type = N'P' ORDER BY number) AS x; 

SET @sql = N'SELECT Account ' + @dc1 + 
    ' FROM (SELECT Account, Contact, rn = ''Contact'' 
     + RTRIM(ROW_NUMBER() OVER (PARTITION BY Account ORDER BY Contact)) 
    FROM dbo.YourTable) AS src PIVOT (MAX(Contact) FOR rn IN (' 
     + STUFF(@dc2, 1, 1, '') + ')) AS p;'; 

EXEC sp_executesql @sql; 

SQLiddle demo

Verwandte Themen