Sql server 使用group by将行动态转换为列

Sql server 使用group by将行动态转换为列,sql-server,group-by,transpose,Sql Server,Group By,Transpose,我正在寻找一个代码,可以使用GROUPBY将行转换为列,下面是我的表格和所需的输出 表格: MR_ID | DR_ID --------|-------- MR_123 | 1 MR_123 | 3 MR_124 | 4 MR_124 | 5 MR_124 | 6 MR_125 | 0 渴望输出: MR_ID | DR_ID_1 | DR_ID_2 | DR_ID_3 --------|----------|----------|-----

我正在寻找一个代码,可以使用GROUPBY将行转换为列,下面是我的表格和所需的输出

表格:

MR_ID  |  DR_ID
--------|--------
MR_123  |   1
MR_123  |   3
MR_124  |   4
MR_124  |   5
MR_124  |   6
MR_125  |   0   
渴望输出:

MR_ID  |  DR_ID_1 |  DR_ID_2 | DR_ID_3 
--------|----------|----------|---------
MR_123  |     1    |    2     |   NULL
MR_124  |     4    |    5     |    6
MR_125  |     0    |   NULL   |   NULL
这里我希望每个DR_ID的每个单独的列都有数字的增量,这应该是动态的

像这样试试:

DECLARE @mockup TABLE(MR_ID VARCHAR(10),DR_ID INT);
INSERT INTO @mockup VALUES
 ('MR_123',1)
,('MR_123',3)
,('MR_124',4)
,('MR_124',5)
,('MR_124',6)
,('MR_125',0);

SELECT p.*
FROM
(
    SELECT *
          ,'DR_ID_' + CAST(ROW_NUMBER() OVER(PARTITION BY MR_ID ORDER BY DR_ID) AS VARCHAR(MAX)) AS columnName
    FROM @mockup AS m
) AS t
PIVOT(MAX(DR_ID) FOR columnName IN(DR_ID_1,DR_ID_2,DR_ID_3,DR_ID_4)) AS p;

“动态列名”是用
行号()创建的。

您也可以使用动态sql查询

查询

declare @sql as varchar(max);
select @sql = 'select t.MR_ID, ' + stuff((
    select distinct ', max(case t.[rn] when ' 
    + cast(t.[rn] as varchar(10)) + ' then t.[DR_ID] end) 
    [DR_ID' + cast(t.[rn] as varchar(10)) + ']' 
    from (
        select [rn] = row_number() 
        over(partition by MR_ID order by DR_ID), *
        from your_table_name
    )t
    for xml path('')
), 1, 2, '')
+ ' from (select [rn] = row_number() over(partition by MR_ID order by DR_ID), * 
  from your_table_name)t
  group by t.[MR_ID];';

exec(@sql);

试试这个

    create table  #tmp (MR_ID varchar(50),DR_ID int)
insert into  #tmp VALUES
('MR_123', 1),('MR_123', 3),('MR_124', 4),('MR_124', 5)
,('MR_124', 6),('MR_125', 0)

 declare @DRCol varchar(50)
 declare @Prefix varchar(20)='DR_'
 ;With CTE as
 (
select *
,ROW_NUMBER()over(partition by MR_ID order by DR_ID)rn
 from #tmp
 )

 select top 1 
@DRCol=stuff((select ','+'['+@Prefix+cast(rn as varchar)+']' 
 from cte c1 where c.mr_id=c1.mr_id for xml path('')),1,1,'')
 from cte c
 where c.mr_id=(select top 1 mr_id from cte c1 order by rn desc)


 declare @Sql varchar(2000)=''

 set @Sql='   SELECT p.*
FROM
(
  SELECT *
          ,'''+@Prefix+'''+ cast(ROW_NUMBER() OVER(PARTITION BY MR_ID ORDER BY DR_ID) as varchar(max))  columnName
    FROM #tmp AS m
    ) AS t
PIVOT(MAX(DR_ID) FOR columnName IN('+@DRCol+')) AS p'
print @sql
exec(@sql)
drop table #tmp

您好,Ullas感谢您的回复,您能做些更多的帮助来理解它吗。此代码在38个以上的DR_ID上不起作用,因为它超过了变量存储限制。我收到这三个错误。1) “无法将默认值分配给局部变量。”2“必须声明标量变量“@Prefix”,3“关键字“order”附近的语法不正确”。@Jayank:我在查询中没有使用名为
@Prefix
的变量。1)在
(CAST(ROW\u NUMBER
)之前缺少
+
。”您缺少
AS columnName
(在
MAX之后))
和3)动态方法无法知道声明的表变量,因为它超出范围…@Shnugo,谢谢。我忘记了在动态sql中您不使用表变量。这是唯一的错误。其次,毫无疑问,我复制了您的sql的一部分。@KumarHarsh,我遇到了Order by的错误(order by rn)和“@Perfix”的标量变量错误我刚刚复制了脚本,运行时没有任何错误。抛出更多详细信息。我收到这三个错误。1)“无法为局部变量指定默认值。”2)“必须声明标量变量“@Prefix”,3)“关键字“order”附近的语法不正确。”,在子查询中--为@DRCol设置值时