将相同ID的不同行放在一行中

时间:2014-07-08 15:08:59

标签: sql-server pivot

如何将这些多行放入一行,内容位于不同的列中:

来自:

ID          |   Subject1/Catalog/Session
10868952    |   NUR/3110/D507
10868952    |   NUR/3110/D512
10868952    |   NUR/4010/D523
10868952    |   NUR/4010/HD20

ID       |Subject1/Catalog/Session |Subject2/Catalog/Session | Subject3/Catalog/Session   |Subject4/Catalog/Session | Subject5/Catalog/Session

10868952 |NUR/3110/D507            | NUR/3110/D512           | NUR/4010/D523              | NUR/4010/HD20           | 

2 个答案:

答案 0 :(得分:0)

如果将来您可以提供ddl和示例数据,那将是最好的。我这次为你做了这件事。

如果您知道每行的元素数量,以下是如何执行此操作的方法。我将原始帖子的评论中的链接放到这种方法的静态和动态版本中。

if OBJECT_ID('tempdb..#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';

with OrderedResults as
(
    select *, ROW_NUMBER() over(partition by ID order by Subject1) as RowNum
    from #Something
)

select ID
 , MAX(Case when RowNum = 1 then Subject1 end) as Subject1
 , MAX(Case when RowNum = 2 then Subject1 end) as Subject2
 , MAX(Case when RowNum = 3 then Subject1 end) as Subject3
 , MAX(Case when RowNum = 4 then Subject1 end) as Subject4
from OrderedResults
group by ID

答案 1 :(得分:0)

以下是如何将其作为动态支点。这里有很多概念。一个是计数表。在此代码中,它被实现为cte。在我的实际系统中,我将此视为一种观点。它生成10,000行,读取为零。这里的理货表和大多数其他概念都是由不朽的杰夫莫登学习的。如果您不知道计数表是什么或它们是如何工作的,请查看Jeff的文章。 http://www.sqlservercentral.com/articles/T-SQL/62867/

我将发布一些代码来说明如何为这个例子做这个,但任何不熟悉这种技术的人都应该阅读他的文章。 http://www.sqlservercentral.com/articles/Crosstab/65048/

这是一个完整的工作示例,将其作为动态交叉表。如果您确信这个生成的sql是安全的,请随意取消注释最后两行。

最后但并非最不重要。确保您完全了解此代码及其工作原理。当出现问题时,我的手机不会在凌晨3点响起。您是必须在那里支持此代码的人。

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