SQL Server 2008 Management Studio:将行数据转换为列

时间:2014-07-17 18:55:57

标签: sql sql-server sql-server-2008

我已尝试查看有关该主题的其他帖子,但我见过的所有示例都基于了解特定值。

我的例子:

Address       Name     Number
-------      -------   -------
1234 Main     Bob      555-555-5555
1234 Main     Karen    444-444-4444
1990 Maple    Susie    333-333-3333
1010 12th     Joe      222-222-2222
1010 12th     Beth     111-111-1111
1010 12th     Steve    444-433-3221

我想要的例子:

Address     Contact1               Contact2              Contact3
-------      -------               --------              --------
1234 Main    Bob:555-555-5555     Karen:444-444-4444     NULL
1990 Maple   Susie:333-333-3333      NULL                NULL
1010 12th    Joe: 222-222-2222    Beth 111-111-1111    Steve 444-433-3221

有成千上万的行,所以我不能这样做......我在这里失去了一点点。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

动态数据透视图可以使用,但动态交叉表也可以。一般来说,交叉表将击败枢轴以获得性能。这是我几天前发布的一个例子。

if OBJECT_ID('Something') is not null
    drop table Something

create table Something
(
    ID int,
    Subject1 varchar(50)
)

insert Something
select 10868952, 'NUR/3110/D507' union all
select 10868952, 'NUR/3110/D512' union all
select 10868952, 'NUR/4010/D523' union all
select 10868952, 'NUR/4010/HD20' union all
select 12345, 'asdfasdf'
declare @MaxCols int

declare @StaticPortion nvarchar(2000) = 
    'with OrderedResults as
    (
        select *, ROW_NUMBER() over(partition by ID order by Subject1) as RowNum
        from Something
    )
    select ID';

declare @DynamicPortion nvarchar(max) = '';
declare @FinalStaticPortion nvarchar(2000) = ' from OrderedResults Group by ID order by ID';

with E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS 
(
    SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)

select @DynamicPortion = @DynamicPortion + 
    ', MAX(Case when RowNum = ' + CAST(N as varchar(6)) + ' then Subject1 end) as Subject' + CAST(N as varchar(6)) + CHAR(10)
from cteTally t
where t.N <= 
(
    select top 1 Count(*)
    from Something
    group by ID
    order by COUNT(*) desc
)

select @StaticPortion + @DynamicPortion + @FinalStaticPortion

declare @SqlToExecute nvarchar(max) = @StaticPortion + @DynamicPortion + @FinalStaticPortion;
exec sp_executesql @SqlToExecute

答案 1 :(得分:1)

我认为您可以使用以下查询。假设您有最多三个联系人

;WITH orderedAddress(Address,Name,Number,Sort)
AS
(
SELECT Address,Name,Number,ROW_NUMBER() OVER(PARTITION BY Address ORDER BY Name) AS num
FROM Addresses
)
SELECT main.Address,Contact1.Name + ':' + Contact1.Number AS Contact1 ,
Contact2.Name + ':' + ISNULL(Contact2.Number,'') AS Contact2 ,
Contact3.Name + ':' + ISNULL(Contact3.Number,'') AS Contact3 
FROM
(SELECT DISTINCT Address FROM Addresses) AS main
LEFT JOIN OrderedAddress Contact1 ON main.Address = Contact1.Address AND Contact1.Sort=1
LEFT JOIN OrderedAddress Contact2 ON main.Address = Contact2.Address AND Contact2.Sort=2
LEFT JOIN OrderedAddress Contact3 ON main.Address = Contact3.Address AND Contact3.Sort=3