如何解决在SQL Server中将行动态转置为列
我想将下面的行动态转换为列。
**Process Id Attribute Values**
1 Equipment Normal
1 Complaints No
1 Availability 30 min
2 Phone1 123456789
2 Phone2 987654321
我试图解决这个问题,但无法获得预期的结果。我需要以下输出
Process ID Attribute1 Value1 Arrtibute2 Value2 Attribute3 Value3
1 Equipment Normal Complaints No Availability 30 min
2 Phone1 123456789 Phone2 987654321 NULL NULL
一个进程可以具有一个或多个属性。因此,如果一个流程具有10个属性,则应在所需的输出中创建10列。有什么建议吗?
解决方法
所有最新的ANSI兼容数据库都应支持此功能。没有DBMS,我坚持使用最新的ANSI标准。
WITH
-- your input
input(Process_Id,Attribute,Values) AS (
SELECT 1,'Equipment','Normal'
UNION ALL SELECT 1,'Complaints','No'
UNION ALL SELECT 1,'Availability','30 min'
UNION ALL SELECT 2,'Phone1','123456789'
UNION ALL SELECT 2,'Phone2','987654321'
),-- need a sequence counter ...
with_seq AS (
SELECT
ROW_NUMBER() OVER(PARTITION BY process_id) AS seq,*
FROM input
)
SELECT
process_id,MAX(CASE seq WHEN 1 THEN attribute END) AS attrib1,MAX(CASE seq WHEN 1 THEN values END) AS val1,MAX(CASE seq WHEN 2 THEN attribute END) AS attrib2,MAX(CASE seq WHEN 2 THEN values END) AS val2,MAX(CASE seq WHEN 3 THEN attribute END) AS attrib3,MAX(CASE seq WHEN 3 THEN values END) AS val3
FROM with_seq
GROUP BY process_id;
-- out process_id | attrib1 | val1 | attrib2 | val2 | attrib3 | val3
-- out ------------+-----------+-----------+------------+-----------+--------------+-------
-- out 1 | Equipment | Normal | Complaints | No | Availability | 30 min
-- out 2 | Phone1 | 123456789 | Phone2 | 987654321 | |
,
请尝试以下代码。它将提供所需的输出。
My sample Algorithm
1. Create manual named columns by using ROW_NUMBER()
2. Create Dynamic columns for Attribute,Value named as @columnsAttribute,@columnsValue
3. Create Dynamic group by columns for both Attribute & Value named as @Allcolumns
4. Dynamic query creation with pivot for both Attribute & Value
declare @tblAttribute as
table(processid int,attribute NVARCHAR(100),value NVARCHAR(200))
insert into @tblAttribute(processid,attribute,value)
values(1,'Normal'),(1,'No'),'30 min'),'test','testvalue'),(2,'123456789'),'987654321')
;with ctetbl as
(
select ROW_NUMBER() over (partition by processid order by processid) rno,* from @tblAttribute
),ctetbl1 as
(
select processid,'Attribute'+ cast(rno as NVARCHAR(2)) as DynamicAttribute,'Value'+cast(rno as NVARCHAR(2)) as DyanamicValue,value from ctetbl
)
select * into #tblDynamicAttribute from ctetbl1
declare @Allcolumns as NVARCHAR(max),@columnsAttribute as NVARCHAR(max),@columnsValue as NVARCHAR(max),@sql as NVARCHAR(MAX) = ''
select @Allcolumns=coalesce(@Allcolumns+',','')+'max('+QUOTENAME(B.DynamicAttribute)+') as '+ QUOTENAME(B.DynamicAttribute) +',max('+QUOTENAME(B.DyanamicValue)+') as '+ QUOTENAME(B.DyanamicValue)
from (select distinct DynamicAttribute,DyanamicValue from #tblDynamicAttribute) as B
order by b.DynamicAttribute
select @columnsAttribute=coalesce(@columnsAttribute+','')+QUOTENAME(B.DynamicAttribute)
from (select distinct DynamicAttribute,DyanamicValue from #tblDynamicAttribute) as B
order by b.DynamicAttribute
select @columnsValue=coalesce(@columnsValue+','')+QUOTENAME(B.DyanamicValue)
from (select distinct DynamicAttribute,DyanamicValue from #tblDynamicAttribute) as B
order by b.DynamicAttribute
-- construct dynamic SQL
SET @sql ='
select x.processid,' + @Allcolumns +' from (
SELECT processid,' + @columnsAttribute+','+ @columnsValue +' FROM
(
SELECT
processid,value,dynamicattribute,DyanamicValue
FROM
#tblDynamicAttribute p
) t
PIVOT(
max(attribute)
FOR dynamicattribute IN ('+ @columnsAttribute +')
) AS pivot_table
PIVOT(
max(value)
FOR DyanamicValue IN ('+ @columnsValue +')
) AS pivot_table1
) x group by processid;';
-- execute the dynamic SQL
EXECUTE sp_executesql @sql;
drop table #tblDynamicAttribute
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。