2

我有一个名为SectionNames如下的表

SectionID SectionCode 小节
   1 xYz 个人
   2 xYz 家庭
   3 CYD 朋友
   4 PCPO 1 级
   5 PCPO 2 级
   6 PCPO 3 级

很快。所以将来我们可以为每个部分代码添加一个或多个小节。

并且还有一张表,它是上SectionNames表和Employee员工数据表的参考表。

ID EmployeeID SectionID 成本    
1 1 1 $200
2 1 2 $300    
3 1 3 $40
4 1 4 $10
5 1 5 无等级
6 1 6 无级别
7 1 7 $20
8 1 8 无级别
9 1 9 无级别

所以我希望这些表的输出应该如下所示:

EmployeeID     Individual_xyz_Cost    Family_xyz_Cost    Friends_xyz_cost  level1_PCPO_cost  level2_PCPO_Cost
   1                 $200                 $300               $400              $10             NoLevel

我的员工表中几乎没有员工记录。我希望这是动态的。就像如果将来如果Relatives再为部分添加一个小节,XYZ那么我的查询应该返回Relatives_XYZ_Cost

如何动态编写此查询?

4

1 回答 1

6

您将希望使用该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;

请参阅SQL Fiddle with Demo

如果您需要灵活的查询,则将其转换为使用动态 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)

请参阅带有演示的 SQL Fiddle

两者的结果是:

| 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 |
于 2013-03-14T16:18:55.587 回答