2014-01-08 38 views
5

我有以下數據集轉置行和列,沒有聚集

Account Contact 

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

我想輸出如下:

Account Contact1 Contact2 Contact3 Contact4 

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

的問題也是我的賬戶&的固定量聯繫方式的非固定數量的

回答

9

如果你要申請的PIVOT功能,您將需要使用集合函數來得到結果,但你會也希望使用窗口功能,如row_number()爲帳戶中的每個聯繫人生成唯一序列。

首先,你將查詢數據類似於:

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

SQL Fiddle with Demo。這將創建一個新列具有唯一的序列:

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

如果你有列的數量有限,那麼你可以硬編碼查詢:

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; 

SQL Fiddle with Demo

如果你有不明數量的列,那麼你將不得不使用動態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; 

SQL Fiddle with Demo。這兩種會給你的結果:

| 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

只是一個稍微不同的方式來生成動態PIVOT

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