在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

样本输出 Dynamic Pivot

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...