当前位置: 代码迷 >> Sql Server >> sql 行转列,并让列值作为行解决思路
  详细解决方案

sql 行转列,并让列值作为行解决思路

热度:108   发布时间:2016-04-24 08:51:11.0
sql 行转列,并让列值作为行
数据源

TaskName PositionName ApprovalRight PositionType ApprovalIndex
入伙联合检查 项目公司土建工程师 0 1 20
入伙联合检查 项目公司工程部副经理(土建) 0 1 40
入伙联合检查 项目公司工程部经理 0 1 60
入伙联合检查 项目公司分管工程副总经理 1 1 100
入伙联合检查 项目公司工程组组长 2 1 120
入伙联合检查 项目公司总经理 2 1 140
入伙联合检查 中心计划部项目经理 0 2 180
入伙联合检查 中心计划部分管副总经理 0 2 200
入伙联合检查 中心计划部总经理 2 2 220
入伙联合检查 分管计划总裁助理 2 2 240
入伙联合检查 物管公司总部分管业务副总经理 6 8 260
销售物料印刷制作 项目公司销售部策划主管 0 1 40
销售物料印刷制作 项目公司销售部经理 0 1 60
销售物料印刷制作 项目公司分管营销副总经理 1 1 100
销售物料印刷制作 项目公司总经理 2 1 140
销售物料印刷制作 中心营销部项目经理 0 2 160
销售物料印刷制作 中心营销部分管副总经理 0 2 180
销售物料印刷制作 中心营销部总经理 0 2 200
销售物料印刷制作 分管营销总裁助理 2 2 220
销售物料印刷制作 分管项目副总裁 2 2 240

需要变换为:

------解决思路----------------------



;with tbl as
(
select '入伙联合检查' as TaskName, '项目公司土建工程师' as PositionName, 
'0'as ApprovalRight, '1'as PositionType, '20' as ApprovalIndex
union all
select '入伙联合检查', '项目公司工程部副经理(土建)', '0', '1', '40'
union all
select '入伙联合检查', '项目公司工程部经理', '0', '1', '60' 
union all
select '入伙联合检查', '项目公司分管工程副总经理', '1', '1', '100'
union all
select '入伙联合检查', '中心计划部项目经理', '0', '2', '180'
union all
select '入伙联合检查', '中心计划部分管副总经理', '0', '2', '200'
),
ct1 as 
(
select ROW_NUMBER() over(partition by TaskName, PositionType order by TaskName) as tid, * from tbl
),
ct2 as
(
select TaskName from tbl group by TaskName
)
select ct2.TaskName, 
t1.PositionName as [1], t2.PositionName as [1], 
t3.PositionName as [1], t4.PositionName as [1],
t5.PositionName as [2], t6.PositionName as [2]
from ct2 
left join
(select TaskName, PositionName from ct1 where tid = 1 and PositionType = 1) as t1  -- 类别为1 的第一列数据
on ct2.TaskName = t1.TaskName
left join
(select TaskName, PositionName from ct1 where tid = 2 and PositionType = 1) as t2  -- 类别为1 的第二列数据
on ct2.TaskName = t2.TaskName
left join
(select TaskName, PositionName from ct1 where tid = 3 and PositionType = 1) as t3
on ct2.TaskName = t3.TaskName
left join
(select TaskName, PositionName from ct1 where tid = 4 and PositionType = 1) as t4
on ct2.TaskName = t4.TaskName
left join
(select TaskName, PositionName from ct1 where tid = 1 and PositionType = 2) as t5  -- 类别为2 的第一列数据
on ct2.TaskName = t5.TaskName
left join
(select TaskName, PositionName from ct1 where tid = 1 and PositionType = 2) as t6  -- 类别为2 的第二列数据
on ct2.TaskName = t6.TaskName


-----------------------------------------------------------------------------
TaskName  1                      1                                   1                           1                         2                                         2
入伙联合检查 项目公司土建工程师 项目公司工程部副经理(土建) 项目公司工程部经理 项目公司分管工程副总经理 中心计划部项目经理 中心计划部项目经理



静态写法,需要你知道有多少类和多少列。

------解决思路----------------------
参考动态行转列:
http://www.cnblogs.com/maanshancss/archive/2013/03/13/2957108.html
------解决思路----------------------
/* 测试数据
WITH table1(TaskName,PositionName,ApprovalRight,PositionType,ApprovalIndex)AS(
    SELECT '入伙联合检查','项目公司土建工程师',0,1,20 UNION ALL
    SELECT '入伙联合检查','项目公司工程部副经理(土建)',0,1,40 UNION ALL
    SELECT '入伙联合检查','项目公司工程部经理',0,1,60 UNION ALL
    SELECT '入伙联合检查','项目公司分管工程副总经理',1,1,100 UNION ALL
    SELECT '入伙联合检查','项目公司工程组组长',2,1,120 UNION ALL
    SELECT '入伙联合检查','项目公司总经理',2,1,140 UNION ALL
    SELECT '入伙联合检查','中心计划部项目经理',0,2,180 UNION ALL
    SELECT '入伙联合检查','中心计划部分管副总经理',0,2,200 UNION ALL
    SELECT '入伙联合检查','中心计划部总经理',2,2,220 UNION ALL
    SELECT '入伙联合检查','分管计划总裁助理',2,2,240 UNION ALL
    SELECT '入伙联合检查','物管公司总部分管业务副总经理',6,8,260 UNION ALL
    SELECT '销售物料印刷制作','项目公司销售部策划主管',0,1,40 UNION ALL
    SELECT '销售物料印刷制作','项目公司销售部经理',0,1,60 UNION ALL
    SELECT '销售物料印刷制作','项目公司分管营销副总经理',1,1,100 UNION ALL
    SELECT '销售物料印刷制作','项目公司总经理',2,1,140 UNION ALL
    SELECT '销售物料印刷制作','中心营销部项目经理',0,2,160 UNION ALL
    SELECT '销售物料印刷制作','中心营销部分管副总经理',0,2,180 UNION ALL
    SELECT '销售物料印刷制作','中心营销部总经理',0,2,200 UNION ALL
    SELECT '销售物料印刷制作','分管营销总裁助理',2,2,220 UNION ALL
    SELECT '销售物料印刷制作','分管项目副总裁',2,2,240
)*/
SELECT Convert(nvarchar(15),TaskName) TaskName,
       Convert(nvarchar(15),PositionName) PositionName,
       Convert(nvarchar(15),PositionType) PositionType,
       PositionType * 100 + (ROW_NUMBER() OVER(PARTITION BY TaskName, PositionType
                                               ORDER BY ApprovalIndex)
                            ) rn
  INTO #t
  FROM table1

DECLARE @sql nvarchar(max)
DECLARE @columns nvarchar(max)

SET @columns = ''
    SELECT @columns=@columns+N',['+convert(nvarchar(11),rn)+N']'
      FROM #t
  GROUP BY rn
  ORDER BY rn

SET @columns = STUFF(@columns,1,1,'')

SET @sql = N'
SELECT *
  FROM (SELECT Convert(nvarchar(15),'''') TaskName,
               PositionType,
               rn
          FROM #t
       ) a1
 PIVOT (MAX(PositionType)
        FOR rn IN ('+@columns+N')
       ) p1
UNION ALL
SELECT *
  FROM (SELECT TaskName,
               PositionName,
               rn
          FROM #t
       ) a2
 PIVOT (MAX(PositionName)
        FOR rn IN ('+@columns+N')
       ) p2'

PRINT @sql

EXEC sp_executesql @sql

动态语句
SELECT *
  FROM (SELECT Convert(nvarchar(15),'') TaskName,
               PositionType,
               rn
          FROM #t
       ) a1
 PIVOT (MAX(PositionType)
        FOR rn IN ([101],[102],[103],[104],[105],[106],[201],[202],[203],[204],[205],[801])
       ) p1
UNION ALL
SELECT *
  FROM (SELECT TaskName,
               PositionName,
               rn
          FROM #t
       ) a2
 PIVOT (MAX(PositionName)
        FOR rn IN ([101],[102],[103],[104],[105],[106],[201],[202],[203],[204],[205],[801])
       ) p2

结果
TaskName           101                     102                         103                       104                       105                 106             201                 202                     203               204               205             801
------------------ ----------------------- --------------------------- ------------------------- ------------------------- ------------------- --------------- ------------------- ----------------------- ----------------- ----------------- --------------- -----------------------------
                   1                       1                           1                         1                         1                   1               2                   2                       2                 2                 2               8
入伙联合检查       项目公司土建工程师      项目公司工程部副经理(土建)项目公司工程部经理        项目公司分管工程副总经理  项目公司工程组组长  项目公司总经理  中心计划部项目经理  中心计划部分管副总经理  中心计划部总经理  分管计划总裁助理  NULL            物管公司总部分管业务副总经理
销售物料印刷制作   项目公司销售部策划主管  项目公司销售部经理          项目公司分管营销副总经理  项目公司总经理            NULL                NULL            中心营销部项目经理  中心营销部分管副总经理  中心营销部总经理  分管营销总裁助理  分管项目副总裁  NULL
  相关解决方案