的关键是,包括在row_number()
declare @cols nvarchar(max);
declare @sql nvarchar(max);
select @cols = stuff((
select distinct
',' + quotename('mm_'
+ right('0' +convert(nvarchar(10),row_number() over (
partition by trac_id
order by contact
)),2)
)
from t
for xml path (''), type).value('.','nvarchar(max)')
,1,1,'');
select @sql = '
select trac_id, ' + @cols + '
from (
select
trac_id
, contact = convert(char(10),contact,120)
, rn=''mm_''+right(''0'' +convert(nvarchar(10),row_number() over (
partition by trac_id
order by contact
)),2)
from t
) as a
pivot (max([contact]) for [rn] in (' + @cols + ')) p';
select @sql as CodeGenerated;
exec sp_executesql @sql;
rextester演示partition by trac_id
:http://rextester.com/XDVOTD39040
回报:
+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| CodeGenerated |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| select trac_id, [mm_01],[mm_02],[mm_03],[mm_04],[mm_05],[mm_06],[mm_07],[mm_08],[mm_09],[mm_10],[mm_11],[mm_12],[mm_13],[mm_14] |
| from ( |
| select |
| trac_id |
| , contact = convert(char(10),contact,120) |
| , rn='mm_'+right('0' +convert(nvarchar(10),row_number() over ( |
| partition by trac_id |
| order by contact |
| )),2) |
| from t |
| ) as a |
| pivot (max([contact]) for [rn] in ([mm_01],[mm_02],[mm_03],[mm_04],[mm_05],[mm_06],[mm_07],[mm_08],[mm_09],[mm_10],[mm_11],[mm_12],[mm_13],[mm_14])) p |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
和
+---------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+
| trac_id | mm_01 | mm_02 | mm_03 | mm_04 | mm_05 | mm_06 | mm_07 | mm_08 | mm_09 | mm_10 | mm_11 | mm_12 | mm_13 | mm_14 |
+---------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+
| 001 | 2017-03-01 | 2017-03-08 | 2017-03-13 | 2017-03-16 | 2017-03-16 | 2017-03-17 | 2017-03-22 | 2017-03-23 | 2017-03-23 | 2017-03-24 | 2017-03-27 | 2017-03-27 | 2017-03-30 | 2017-03-31 |
| 005 | 2017-02-16 | 2017-03-08 | 2017-03-18 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 011 | 2017-02-16 | 2017-03-01 | 2017-03-23 | 2017-03-30 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 013 | 2017-03-08 | 2017-03-13 | 2017-03-16 | 2017-03-16 | 2017-03-17 | 2017-03-22 | 2017-03-23 | 2017-03-24 | 2017-03-27 | 2017-03-27 | 2017-03-30 | 2017-03-30 | 2017-03-31 | NULL |
| 040 | 2017-02-20 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 043 | 2017-02-03 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 059 | 2017-03-08 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 060 | 2017-02-08 | 2017-03-07 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 067 | 2017-01-24 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 068 | 2017-02-13 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
+---------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+
要null
值转换为空字符串:
declare @cols nvarchar(max);
declare @select_cols nvarchar(max);
declare @sql nvarchar(max);
select @cols = stuff((
select distinct
',' + quotename('mm_'
+ right('0' +convert(nvarchar(10),row_number() over (
partition by trac_id
order by contact
)),2)
)
from t
for xml path (''), type).value('.','nvarchar(max)')
,1,1,'');
select @select_cols = (
select distinct
char(10)+' , ' + quotename('mm_'
+ right('0' +convert(nvarchar(10),row_number() over (
partition by trac_id
order by contact
)),2)
) +' = isnull('+
quotename('mm_'
+ right('0' +convert(nvarchar(10),row_number() over (
partition by trac_id
order by contact
)),2)
)+','''')'
from t
for xml path (''), type).value('.','nvarchar(max)')
select @sql = '
select trac_id' + @select_cols + '
from (
select
trac_id
, contact = convert(char(10),contact,120)
, rn=''mm_''+right(''0'' +convert(nvarchar(10),row_number() over (
partition by trac_id
order by contact
)),2)
from t
) as a
pivot (max([contact]) for [rn] in (' + @cols + ')) p';
select @sql as CodeGenerated;
exec sp_executesql @sql;
rextester演示:http://rextester.com/HDTK5946
回报:
+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| CodeGenerated |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| select trac_id |
| , [mm_01] = isnull([mm_01],'') |
| , [mm_02] = isnull([mm_02],'') |
| , [mm_03] = isnull([mm_03],'') |
| , [mm_04] = isnull([mm_04],'') |
| , [mm_05] = isnull([mm_05],'') |
| , [mm_06] = isnull([mm_06],'') |
| , [mm_07] = isnull([mm_07],'') |
| , [mm_08] = isnull([mm_08],'') |
| , [mm_09] = isnull([mm_09],'') |
| , [mm_10] = isnull([mm_10],'') |
| , [mm_11] = isnull([mm_11],'') |
| , [mm_12] = isnull([mm_12],'') |
| , [mm_13] = isnull([mm_13],'') |
| , [mm_14] = isnull([mm_14],'') |
| from ( |
| select |
| trac_id |
| , contact = convert(char(10),contact,120) |
| , rn='mm_'+right('0' +convert(nvarchar(10),row_number() over ( |
| partition by trac_id |
| order by contact |
| )),2) |
| from t |
| ) as a |
| pivot (max([contact]) for [rn] in ([mm_01],[mm_02],[mm_03],[mm_04],[mm_05],[mm_06],[mm_07],[mm_08],[mm_09],[mm_10],[mm_11],[mm_12],[mm_13],[mm_14])) p |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
和
+---------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+
| trac_id | mm_01 | mm_02 | mm_03 | mm_04 | mm_05 | mm_06 | mm_07 | mm_08 | mm_09 | mm_10 | mm_11 | mm_12 | mm_13 | mm_14 |
+---------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+
| 001 | 2017-03-01 | 2017-03-08 | 2017-03-13 | 2017-03-16 | 2017-03-16 | 2017-03-17 | 2017-03-22 | 2017-03-23 | 2017-03-23 | 2017-03-24 | 2017-03-27 | 2017-03-27 | 2017-03-30 | 2017-03-31 |
| 005 | 2017-02-16 | 2017-03-08 | 2017-03-18 | | | | | | | | | | | |
| 011 | 2017-02-16 | 2017-03-01 | 2017-03-23 | 2017-03-30 | | | | | | | | | | |
| 013 | 2017-03-08 | 2017-03-13 | 2017-03-16 | 2017-03-16 | 2017-03-17 | 2017-03-22 | 2017-03-23 | 2017-03-24 | 2017-03-27 | 2017-03-27 | 2017-03-30 | 2017-03-30 | 2017-03-31 | |
| 040 | 2017-02-20 | | | | | | | | | | | | | |
| 043 | 2017-02-03 | | | | | | | | | | | | | |
| 059 | 2017-03-08 | | | | | | | | | | | | | |
| 060 | 2017-02-08 | 2017-03-07 | | | | | | | | | | | | |
| 067 | 2017-01-24 | | | | | | | | | | | | | |
| 068 | 2017-02-13 | | | | | | | | | | | | | |
+---------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+
很多次anks @SqlZim。所以,用source temp表的名称替换你列出的't',给了我后面的东西。最后一个问题是,我可以将它插入一个新的临时表吗? – Erik
@Erik当然。您可以在动态代码'select ... into ## pivoted'内使用全局临时表,例如http://rextester.com/EQDH71409 – SqlZim
如果我只是添加select *到## pivoted我得到以下错误:一个对象或列名缺失或空。对于SELECT INTO语句,请确认每列都有一个名称。对于其他语句,查找空的别名。别名定义为“”或[]是不允许的。将别名更改为有效的名称。 – Erik