SQL将一行转换为多行

时间:2012-10-24 16:18:38

标签: sql sql-server-2008-r2 pivot

我有一个包含许多列的SQL表,特别是包含代码的一组列。对于每个代码列,还存在与每个代码列有关的对应信息列。我需要能够将一条记录转换成多条返回的记录(即每个代码一条记录)。这是一个包含遗留数据和软件代码的旧表,并且很难对表进行规范化(即使它确实需要)。

这是表格:

CO_ComapnyInformation
                (
                 ProjectID
                ,SubContractor_OrgID
                ,BudGet
                ,ContractDays
                ,ContractCode
                ,ContractCode1
                ,ContractCode2
                ,ContractCode3
                ,ContractCode4
                ,ContractCode5
                ,ContractCodeAmt
                ,ContractCode1Amt
                ,ContractCode2Amt
                ,ContractCode3Amt
                ,ContractCode4Amt
                ,ContractCode5Amt
                ,ContractStartDate
                ,ContractCodeBudget
                ,ContractCodeBudget1
                ,ContractCodeBudget2
                ,ContractCodeBudget3
                ,ContractCodeBudget4
                ,ContractCodeBudget5
                ,ContractCodeAdjust
                ,ContractCodeAdjust1
                ,ContractCodeAdjust2
                ,ContractCodeAdjust3
                ,ContractCodeAdjust4
                ,ContractCodeAdjust5
                ,ContractCodeUncommit
                ,ContractCodeUncommit1
                ,ContractCodeUncommit2
                ,ContractCodeUncommit3
                ,ContractCodeUncommit4
                ,ContractCodeUncommit5
                ,ContractCodeSaveOR
                ,ContractCodeSaveOR1
                ,ContractCodeSaveOR2
                ,ContractCodeSaveOR3
                ,ContractCodeSaveOR4
                ,ContractCodeSaveOR5
                )

基本上我需要返回的记录集如下所示:

Contract Code | Contract Budget | Contract Adjust | Contract Uncommit | Contract SaveOR | Pro_ID | ...
ContractCode    10.00             xxxx
ContractCode1
ContractCode2

等...

仅当COntractCode列中包含数据时。

我该怎么做?

2 个答案:

答案 0 :(得分:3)

您可以使用union all来执行此操作。

select 'ContractCode' as ContractCodeType, ContractCode, ContractCodeBudget, ...
from CO_ComapnyInformation

union all

select 'ContractCode1' as ContractCodeType, ContractCode1, ContractCodeBudget1, ...
from CO_ComapnyInformation

...

也许您不需要第一列(ContractCodeType),这样您就可以知道该行来自哪一组值。

理想情况下,如果这些字段存储相同类型的信息,最好只使用一个字段集来创建一个更简单的表。您可以从它上面的视图开始(这基本上就是上面的union代码),并以小步骤重构您的应用程序。

答案 1 :(得分:1)

您应该可以通过使用SQLServer的pivot / unpivot功能从基表中选择一个来执行此操作 - 例如:

select ProjectID, 
       Contract_Code, 
       max(Budget) Budget, 
       max(Adjust) Adjust, 
       max(Uncommit) Uncommit, 
       max(SaveOR) SaveOR
from
(select ProjectID, vals, left(cols,1,13) Contract_Code, right(cols,len(cols)-13) col_head from
 (select ProjectID,
         ContractCodeBudget  ContractCode_Budget,
         ContractCodeBudget1 ContractCode1Budget,
         ContractCodeBudget2 ContractCode2Budget,
         ContractCodeBudget3 ContractCode3Budget,
         ContractCodeBudget4 ContractCode4Budget,
         ContractCodeBudget5 ContractCode5Budget,
         ContractCodeAdjust  ContractCode_Adjust,
         ContractCodeAdjust1 ContractCode1Adjust,
         ContractCodeAdjust2 ContractCode2Adjust,
         ContractCodeAdjust3 ContractCode3Adjust,
         ContractCodeAdjust4 ContractCode4Adjust,
         ContractCodeAdjust5 ContractCode5Adjust,
         ContractCodeUncommit  ContractCode_Uncommit,
         ContractCodeUncommit1 ContractCode1Uncommit,
         ContractCodeUncommit2 ContractCode2Uncommit,
         ContractCodeUncommit3 ContractCode3Uncommit,
         ContractCodeUncommit4 ContractCode4Uncommit,
         ContractCodeUncommit5 ContractCode5Uncommit,
         ContractCodeSaveOR  ContractCode_SaveOR,
         ContractCodeSaveOR1 ContractCode1SaveOR,
         ContractCodeSaveOR2 ContractCode2SaveOR,
         ContractCodeSaveOR3 ContractCode3SaveOR,
         ContractCodeSaveOR4 ContractCode4SaveOR,
         ContractCodeSaveOR5 ContractCode5SaveOR
  from CO_ComapnyInformation) t
 unpivot (vals for cols in (ContractCode_Budget,ContractCode1Budget,ContractCode2Budget,ContractCode3Budget,ContractCode4Budget,ContractCode5Budget,
                            ContractCode_Adjust,ContractCode1Adjust,ContractCode2Adjust,ContractCode3Adjust,ContractCode4Adjust,ContractCode5Adjust,
                            ContractCode_Uncommit,ContractCode1Uncommit,ContractCode2Uncommit,ContractCode3Uncommit,ContractCode4Uncommit,ContractCode5Uncommit,
                            ContractCode_SaveOR,ContractCode1SaveOR,ContractCode2SaveOR,ContractCode3SaveOR,ContractCode4SaveOR,ContractCode5SaveOR
                            )
          ) as t1
) as t2
pivot (max(vals) for col_head in ([Budget],[Adjust],[Uncommit],[SaveOR])) as t3
group by ProjectID, Contract_Code