将行转换为像枢轴一样的列

时间:2018-10-08 14:02:52

标签: sql sql-server

表是:

  +----+------+
  | Id | Name |
  +----+------+    
  | 1  | aaa  |
  | 1  | bbb  |
  | 2  | ccc  |
  | 2  | ddd  |
  | 3  | eee  |
  +----+------+

必填输出:

+----+---------------------++---------------------+
| Id |        colum1       |   column2            |
+----+---------------------+ +--------------------+ 
|  1 | aaa                 | |   bbb              |
+----+---------------------++---------------------+
+----+---------------------+ +--------------------+ 
|  2 | ccc                | |   ddd               |
+----+---------------------++---------------------+
+----+---------------------+ +--------------------+ 
|  3 | eee                 | |   null             |
+----+---------------------++---------------------+

我一直在尝试使用“和” a和数据透视,但是如果我有多个id的话,我似乎并不想以正确的方式访问

喜欢图片

3 个答案:

答案 0 :(得分:3)

如果名称数量有限,则可以使用row_number()并进行聚合,否则您将需要使用动态SQL:

select id, 
       max(case when seq = 1 then name end) as col1,
       max(case when seq = 2 then name end) as col2,
       max(case when seq = 3 then name end) as col3,
       . . .
from (select t.*, row_number() over (partition by id order by name) as seq
      from table t
     ) t
group by id;

答案 1 :(得分:2)

您可以使用PIVOT进行此操作。

DECLARE @Tbl  TABLE ( Id INT, Name VARCHAR(10))
INSERT INTO @Tbl VALUES
(1, 'aaa'),
(1, 'bbb'),
(2, 'ccc'),
(2, 'ddd'),
(3, 'eee')

SELECT Id, [1] column1, [2] column2 FROM (
    SELECT *, 
        ROW_NUMBER() OVER(PARTITION BY Id ORDER BY Name) RN 
    FROM @Tbl ) AS SRC PIVOT (MAX(Name) FOR RN IN ([1], [2])) PVT

结果:

Id          column1    column2
----------- ---------- ----------
1           aaa        bbb
2           ccc        ddd
3           eee        NULL

答案 2 :(得分:0)

使用row_number()execute()建立动态查询

--example table
create table #t (Id int, Name varchar(100))
insert into #t values (1,'aaa'),(1,'bbb'),(2,'ccc'),(2,'ddd'),(3,'eee')

-- number of columns to create
declare @columns int
select top 1 @columns = count(*) from #t group by id order by COUNT(*) desc

--build a query
declare @i int = 2, @qry varchar(max) = 'select Id, column1 = max(case when ord = 1 then name end)'

while @i<=@columns begin
    select @qry = @qry + ', column'+cast(@i as varchar(5))+' = max(case when ord = '+cast(@i as varchar(5))+' then name end)'
    set @i = @i + 1
end

select @qry = @qry + '  from (select *, ord = row_number() over (partition by id order by name)
                              from #t
                             ) t
                        group by id'

--execute the query
execute (@qry)

drop table #t