use*_*705 2 sql sql-server pivot
我有一个表,SectionNames如下所示
SectionID SectionCode Subsection 1 xYz Individual 2 xYz Family 3 CYD Friends 4 PCPO level1 5 PCPO level2 6 PCPO level3
等等.因此,将来我们可以为每个部分代码添加一个或多个子部分.
并且还有一个表,它是上SectionNames表和Employee带有员工数据的表的参考表.
ID EmployeeID SectionID Cost 1 1 1 $200 2 1 2 $300 3 1 3 $40 4 1 4 $10 5 1 5 No Level 6 1 6 No Level 7 1 7 $20 8 1 8 No Level 9 1 9 No Level
所以我想从这些表中看出来的应该是这样的:
EmployeeID Individual_xyz_Cost Family_xyz_Cost Friends_xyz_cost level1_PCPO_cost level2_PCPO_Cost
1 $200 $300 $400 $10 NoLevel
Run Code Online (Sandbox Code Playgroud)
员工表中存在很少的员工记录.我希望这是动态的.喜欢如果将来如果Relatives为XYZsection 增加了一个名为add的子部分,那么我的查询应该返回Relatives_XYZ_Cost.
如何动态编写此查询?
您将需要使用该PIVOT函数将数据从列转换为行.如果您将需要未知数量的值作为列,那么您将需要使用动态SQL.
首先可以更容易地看到静态或硬编码版本,然后将其转换为动态SQL版本.当您具有已知数量的值时,将使用静态版本:
select *
from
(
select e.employeeid,
s.subsection +'_'+s.sectioncode+'_Cost' Section,
e.cost
from employee e
inner join sectionnames s
on e.sectionid = s.sectionid
) src
pivot
(
max(cost)
for section in (Individual_xYz_Cost, Family_xYz_Cost,
Friends_CYD_Cost, level1_PCPO_Cost,
level2_PCPO_Cost, level3_PCPO_Cost)
) piv;
Run Code Online (Sandbox Code Playgroud)
如果您需要查询灵活,那么您将转换为使用动态SQL:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(subsection +'_'+sectioncode+'_Cost')
from SectionNames
group by subsection, sectioncode, sectionid
order by sectionid
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT employeeid,' + @cols + '
from
(
select e.employeeid,
s.subsection +''_''+s.sectioncode+''_Cost'' Section,
e.cost
from employee e
inner join sectionnames s
on e.sectionid = s.sectionid
) x
pivot
(
max(cost)
for section in (' + @cols + ')
) p '
execute(@query)
Run Code Online (Sandbox Code Playgroud)
两者的结果是:
| EMPLOYEEID | INDIVIDUAL_XYZ_COST | FAMILY_XYZ_COST | FRIENDS_CYD_COST | LEVEL1_PCPO_COST | LEVEL2_PCPO_COST | LEVEL3_PCPO_COST |
----------------------------------------------------------------------------------------------------------------------------------
| 1 | $200 | $300 | $40 | $10 | No Level | No Level |
Run Code Online (Sandbox Code Playgroud)