我有一张这样的表:
Id Name parentId -------------------------------- 5 Rollers 2 2 Paint and Brushes 1 1 Decorating NULL
使用PIVOT或任何其他单个查询,我可以获得如下输出:
cat1id cat1name cat2id cat2name cat3id cat3Name ------------------------------------------------------------------------ 1 Decorating 2 Paint and Brushes 5 Rollers
答案 0 :(得分:5)
您可以使用PIVOT
,UNPIVOT
和递归查询来执行此操作。
静态版本,您可以将值硬编码为已转换的值:
;with hd (id, name, parentid, category)
as
(
select id, name, parentid, 1 as category
from yourtable
where parentid is null
union all
select t1.id, t1.name, t1.parentid, hd.category +1
from yourtable t1
inner join hd
on t1.parentid = hd.id
),
unpiv as
(
select value, 'cat_'+cast(category as varchar(5))+'_'+ col col_name
from
(
select cast(id as varchar(17)) id, name, parentid, category
from hd
) src
unpivot
(
value for col in (id, name)
) un
)
select [cat_1_id], [cat_1_name],
[cat_2_id], [cat_2_name],
[cat_3_id], [cat_3_name]
from unpiv
pivot
(
max(value)
for col_name in ([cat_1_id], [cat_1_name],
[cat_2_id], [cat_2_name],
[cat_3_id], [cat_3_name])
) piv
动态版本,值在运行时生成:
;with hd (id, name, parentid, category)
as
(
select id, name, parentid, 1 as category
from yourtable
where parentid is null
union all
select t1.id, t1.name, t1.parentid, hd.category +1
from yourtable t1
inner join hd
on t1.parentid = hd.id
)
select category categoryNumber
into #temp
from hd
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + quotename('cat_'+cast(CATEGORYNUMBER as varchar(10))+'_'+col)
from #temp
cross apply (select 'id' col
union all
select 'name' col) src
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = ';with hd (id, name, parentid, category)
as
(
select id, name, parentid, 1 as category
from yourtable
where parentid is null
union all
select t1.id, t1.name, t1.parentid, hd.category +1
from yourtable t1
inner join hd
on t1.parentid = hd.id
),
unpiv as
(
select value, ''cat_''+cast(category as varchar(5))+''_''+ col col_name
from
(
select cast(id as varchar(17)) id, name, parentid, category
from hd
) src
unpivot
(
value for col in (id, name)
) un
)
select '+@cols+'
from unpiv
pivot
(
max(value)
for col_name in ('+@cols+')
) piv'
execute(@query)
drop table #temp
两者的结果相同:
| CAT_1_ID | CAT_1_NAME | CAT_2_ID | CAT_2_NAME | CAT_3_ID | CAT_3_NAME |
--------------------------------------------------------------------------------
| 1 | Decorating | 2 | Paint and Brushes | 5 | Rollers |