我有一个问题,我正在尝试加入同一个表并创建它的列。例如,该表包含id
,name
,type
。
数据可以是:
id name type Date
--------------------------------------------------
1 KKKK BP 05/05/2017
2 MMMM KS 07/10/2016
3 LLL TL 04/05/2017
4 NNN BP 06/01/2016
我想制作一个包含以下设计的表格:
- id name BP KS TL
-------------------------------------------------------------
1 KKK 05/05/2017
2 MMM 07/10/2016
3 LLL 04/05/2017
4 NNN 06/01/2017
我尝试了Pivot表并且没有工作。
有什么想法吗?
答案 0 :(得分:2)
您可以使用SQL Server 2008中的PIVOT
函数将数据行转换为列:
select
id,
name,
BP, KS, TL
from
(
select id,
name,
type,
[date]
from mytable
) d
pivot
(
max([date])
for type in (BP, KS, TL)
) piv;
这也可以使用条件逻辑编写,例如带有一些聚合的CASE
表达式:
select id,
name,
BP = max(case when type = 'BP' then [date] end),
KS = max(case when type = 'KS' then [date] end),
TL = max(case when type = 'TL' then [date] end)
from mytable
group by id, name;
根据您的评论,您可以为每个name
和type
组合设置多个日期,您仍然可以使用类似的查询来使用像row_number
这样的窗口函数得到你想要的最终结果。
如果要使用条件逻辑版本,则需要将查询更改为:
select
name,
BP1 = max(case when type = 'BP' and rn =1 then [date] end),
BP2 = max(case when type = 'BP' and rn =2 then [date] end),
BP3 = max(case when type = 'BP' and rn =3 then [date] end),
KS1 = max(case when type = 'KS' and rn =1 then [date] end),
KS2 = max(case when type = 'KS' and rn =2 then [date] end),
TL1 = max(case when type = 'TL' and rn =1 then [date] end)
from
(
select
name,
[type],
[date],
rn = row_number() over(partition by name, [type] order by [date] desc)
from mytable
) d
group by name;
PIVOT版本将是:
select
name,
BP1, BP2, BP3, KS1, KS2, TL1
from
(
select
name,
type = type + cast(rn as varchar(2)),
[date]
from
(
select
name,
type,
[date],
rn = row_number() over(partition by name, [type] order by [date] desc)
from mytable
)s
) d
pivot
(
max([date])
for type in (BP1, BP2, BP3, KS1, KS2, TL1)
) piv;
正如您所看到的,有很多类型可以获取所有这些列,因此您可以使用动态SQL来获得最终结果:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(Type + cast(rn as varchar(2)))
from
(
select type,
rn = row_number() over(partition by name, type order by date desc)
from mytable
) d
group by type, rn
order by type, rn
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = N'SELECT name, ' + @cols + N'
from
(
select
name,
type = type + cast(rn as varchar(2)),
[date]
from
(
select
name,
type,
[date],
rn = row_number() over(partition by name, [type] order by [date] desc)
from mytable
)s
) x
pivot
(
max(date)
for type in (' + @cols + N')
) p '
exec sp_executesql @query;
我创建了一个demo来表明它们都返回相同的结果。