如何从具有多个不同重复值的行中检索不同的属性到新列中?

时间:2017-12-11 18:52:45

标签: sql-server dynamic-sql

我有一个看起来像这样的表:

att1 att2
| a | 1 |
| a | 2 |
| b | 2 |
| b | 3 |
| c | 1 |
| c | 2 |
| c | 2 |

我需要att1的不同记录,将att1上的重复值分组到一个新列中,如下所示

att1 att2 att3
| a | 1 | 2 |
| b | 2 | 3 |
| c | 1 | 2 |

我试图转动,我试图自我加入,但我似乎无法找到查询来分隔这样的值。有人可以帮帮我吗?感谢

2 个答案:

答案 0 :(得分:0)

您可以使用如下所示的动态数据透视查询 see demo link

create table tt (att1 varchar(10), att2 int)
insert into tt values
('a',1)
,('a',2)
,('b',2)
,('b',3)
,('c',1)
,('c',2)
,('c',2)
go

declare @q varchar(max), @cols varchar(max)
set @cols
     = STUFF((
          SELECT distinct ',' + 
               QUOTENAME('att '+
                         cast(1+ row_number()  over (partition by att1 order by att2 ) as varchar(max))
                        ) 
            FROM (select distinct att1,att2 from tt)tt --note this distinct
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @q=
'select 
  att1,'+ @cols +
' from
(
    select 
       att1,att2,
       ''att ''+
         cast(1+row_number()  over (partition by att1 order by att2 ) as varchar(max))  as r
    from 
       (select distinct att1,att2 from tt)tt 
)I
pivot
( 
    max(att2)   
    for r in ('+@cols+')
 )piv'

 exec(@q)

答案 1 :(得分:0)

这样的任何查询总是闻起来像报告格式,而不是真正的数据要求,这应该在报告工具而不是数据库中完成。但就像所有事情一样,有足够的代码可以实现。

这应该适合你。

create table #t (att1 nvarchar(max) ,att2 int);

insert #t select 'a', 1 union all select 'a', 2;
insert #t select 'b', 2 union all select 'b', 3;
insert #t select 'c', 1 union all select 'c', 2 union all select 'c', 2;

select att1, 1 as att2, 2 as att3 from 
(
    select att1, att2, row_number() over (partition by att1 order by att1, att2) as r
    from (select distinct att1, att2 from #t) as x 
) src
pivot ( avg(att2) for r in ([1],[2])) p;

drop table #t;

第一步是获取表中的不同值,然后按att1对它们进行排序和分组。我使用row_number()命令执行此操作,如下所示:

select att1, att2, row_number() over (partition by att1 order by att1, att2) as r
from (select distinct att1, att2 from #t) as x ;

att1 attr2 r
a    1     1
a    2     2
b    2     1
b    3     2
c    1     1
c    2     2 

从那里,pivot命令将行转换为列。使用pivot命令的问题是这些新列的名称需要是数据驱动的;在row_number命令期间,您可以提供更好的名称,或者您可以像我在此处所做的那样对它们进行别名。

最后,这只适用于只有两个要转动的值的情况。要添加更多内容,请修改for r in ([1], [2])行以包含例如3,4等等