将行数转换为14列作为7个元组

时间:2017-09-07 19:15:34

标签: sql sql-server

我的表格看起来像这样

assignmentID    personID    projectCode projectCodePercent
-------------- ------------ ----------- ----------- 
642             13527       511         75.00
642             13527       621         25.00
650             12000       555         50.00
650             12000       520         25.00
650             12000       621         25.00
240             56000       721         100.00

我想知道(porjectCode,projectCodePercent)作为每个赋值的元组的分布。作业最多可包含7个元组。如果他们没有7那么这些领域可能只是空白。因此,所需的输出应如下所示:

assignmentID    projectCode1  projectCodePercent1   projectCode2   projectCodePercent2   projectCode3   projectCodePercent3   projectCode4   projectCodePercent4   projectCode5   projectCodePercent5   projectCode6   projectCodePercent6   projectCode7   projectCodePercent7
------------    ------------  -------------------   ------------   -------------------   -------------   ------------------- -------------   -------------------   -------------  -------------------   -------------   -------------------  ------------   ----------------
 642            511           75.00                 621            25.00
 650            555           50.00                 520            25.00                 621             25.00
 240            721           100.00

编辑:记录顺序无关紧要。即。只要正确的projectCode匹配正确的projectCodePercent

,哪条记录被分配给projectCode1或projectCode2 ....等等无关紧要

2 个答案:

答案 0 :(得分:4)

DEMO:http://rextester.com/IYDJ29385

  1. CTE为我提供了样本数据
  2. CTE2只为每个assignmentId和PersonId分配行号(您可以使用内联视图)
  3. 然后我们使用case语句根据生成的行号来转动数据。这种方法的缺点是总是返回所有14列。使用动态SQL,您只能在需要时显示这些列。
  4. 这确实假设assignmentId和personId以及projectcode是唯一的。如果同一作业和人员可能存在多个项目代码,那么我们需要做一些不同而不是最大的事情。

    WITH CTE (assignmentID,    personID,    projectCode, projectCodePercent) as  (
    SELECT 642,             13527,       511,         75.00 UNION ALL
    SELECT 642,             13527,       621,         25.00 UNION ALL
    SELECT 650,             12000,       555,         50.00 UNION ALL
    SELECT 650,             12000,       520,         25.00 UNION ALL
    SELECT 650,             12000,       621,         25.00 UNION ALL
    SELECT 240,             56000,       721,         100.00),
    cte2 as (SELECT A.*, row_number() over (partition by AssignmentID, PersonID order by projectCode) RN 
          FROM cte A)
    SELECT AssignmentID
         , PersonID
         , max(CASE WHEN RN = 1 then projectCode end) as projectCode1
         , max(CASE WHEN RN = 1 then ProjectcodePercent end) as ProjectcodePercent1
         , max(CASE WHEN RN = 2 then projectCode end) as projectCode2
         , max(CASE WHEN RN = 2 then ProjectcodePercent end) as ProjectcodePercent2
         , max(CASE WHEN RN = 3 then projectCode end) as projectCode3
         , max(CASE WHEN RN = 3 then ProjectcodePercent end) as ProjectcodePercent3
         , max(CASE WHEN RN = 4 then projectCode end) as projectCode4
         , max(CASE WHEN RN = 4 then ProjectcodePercent end) as ProjectcodePercent4
         , max(CASE WHEN RN = 5 then projectCode end) as projectCode5
         , max(CASE WHEN RN = 5 then ProjectcodePercent end) as ProjectcodePercent5
         , max(CASE WHEN RN = 6 then projectCode end) as projectCode6
         , max(CASE WHEN RN = 6 then ProjectcodePercent end) as ProjectcodePercent6
         , max(CASE WHEN RN = 7 then projectCode end) as projectCode7
         , max(CASE WHEN RN = 7 then ProjectcodePercent end) as ProjectcodePercent7
    FROM CTE2
    Group by AssignmentID, personId
    

    给我们:

    +----+--------------+----------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+
    |    | AssignmentID | PersonID | projectCode1 | ProjectcodePercent1 | projectCode2 | ProjectcodePercent2 | projectCode3 | ProjectcodePercent3 | projectCode4 | ProjectcodePercent4 | projectCode5 | ProjectcodePercent5 | projectCode6 | ProjectcodePercent6 | projectCode7 | ProjectcodePercent7 |
    +----+--------------+----------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+
    |  1 |          650 |    12000 |          520 |               25,00 | 555          | 50,00               | 621          | 25,00               | NULL         | NULL                | NULL         | NULL                | NULL         | NULL                | NULL         | NULL                |
    |  2 |          642 |    13527 |          511 |               75,00 | 621          | 25,00               | NULL         | NULL                | NULL         | NULL                | NULL         | NULL                | NULL         | NULL                | NULL         | NULL                |
    |  3 |          240 |    56000 |          721 |              100,00 | NULL         | NULL                | NULL         | NULL                | NULL         | NULL                | NULL         | NULL                | NULL         | NULL                | NULL         | NULL                |
    +----+--------------+----------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+
    

答案 1 :(得分:3)

因为你不需要动态。一种方法是通过CROSS APPLY对数据进行UNPivot。

示例

Select *
 From (
        Select assignmentID    
              ,B.* 
            From (
                  Select *,Grp = Row_Number() over (Partition By assignmentID  order by projectCode )
                   From  YourTable
                 ) A
            Cross Apply (values ('projectCode'       +left(A.Grp,1),cast(projectCode as varchar(max)))
                               ,('projectCodePercent'+left(A.Grp,1),cast(projectCodePercent as varchar(max)))
                               ,('projectCode'       +left(A.Grp,1),cast(projectCode as varchar(max)))
                        ) B(Item,Value)
      ) A
 Pivot (max([Value]) For [Item] in (projectCode1,projectCodePercent1,projectCode2,projectCodePercent2,projectCode3,projectCodePercent3,projectCode4,projectCodePercent4,projectCode5,projectCodePercent5,projectCode6,projectCodePercent6,projectCode7,projectCodePercent7) ) p

<强>返回

enter image description here