2017-04-21 42 views
1

我创建的存储过程允许用户通过提供PersonID数字作为参数从两个表中检索数据。 我想用枢轴函数动态通过非聚集在多个列和检索数据从ONE柱枢转Data在不同的表中的。下面的两个表格只是示例数据,因为我有超过100列的数据表,因此是动态部分。这两个表没有公共ID列,但只有一个公共列名。 这里是2个表:通过sql中的动态数据透视表聚合多个列

映射表:

CREATE table #table (
ID varchar(10) NOT NULL, 
Column_Name varchar (255) NOT NULL, 
Page_Num varchar(10) NOT NULL, 
Line_Num varchar(10) NOT NULL, 
Element_Num varchar(10) NOT NULL 
) 

INSERT INTO #table (ID,Column_Name,Page_Num,Line_Num,Element_Num) VALUES ('1','Name', 'DT-01', '200','20') 
INSERT INTO #table (ID,Column_Name,Page_Num,Line_Num,Element_Num) VALUES ('2','SSN', 'DT-02', '220','10') 
INSERT INTO #table (ID,Column_Name,Page_Num,Line_Num,Element_Num) VALUES ('3','City', 'DT-03', '300','11') 
INSERT INTO #table (ID,Column_Name,Page_Num,Line_Num,Element_Num) VALUES ('4','StreetName', 'DT-04', '350','33') 
INSERT INTO #table (ID,Column_Name,Page_Num,Line_Num,Element_Num) VALUES ('5','Sex', 'DT-05', '310','51') 

创建:

ID Column_Name  Page_Num Line_Num Element_Num 
_________________________________________________________________ 
    1 Name    DT-01   200   20 
    2 SSN    DT-02   220   10 
    3 City    DT-03   300   11 
    4 StreetName  DT-04   350   33 
    5 Sex    DT-05   310   51 

数据表:

CREATE table #temp (
PersonID varchar (100) NOT NULL, 
Name varchar(100) NOT NULL, 
SSN varchar (255) NOT NULL, 
City varchar(100) NOT NULL, 
StreetName varchar(100) NOT NULL, 
Sex varchar(100) NOT NULL 
) 


INSERT INTO #temp (PersonID,Name,SSN,City,StreetName,Sex) VALUES ('112','Joe','945890189', 'Lookesville', 'Broad st','Male') 
INSERT INTO #temp (PersonID,Name,SSN,City,StreetName,Sex) VALUES ('140','Santana','514819926', 'Falls Church', 'Gane Rd', 'Female') 
INSERT INTO #temp (PersonID,Name,SSN,City,StreetName,Sex) VALUES ('481','Wyatt','014523548','Gainesville', 'Westfield blvd', 'Male') 
INSERT INTO #temp (PersonID,Name,SSN,City,StreetName,Sex) VALUES ('724','Brittany','551489230','Aldi', 'Ostrich rd', 'Female') 
INSERT INTO #temp (PersonID,Name,SSN,City,StreetName,Sex) VALUES ('100','Giovanni','774451362','Paige', 'Company ln', 'Male') 

创建:

PersonID Name   SSN   City   StreetName  Sex 
    _______________________________________________________________________ 
    112  Joe  945890189  Lookesville   Broad st  Male 
    140 Santana 514819926  Falls Church  Gane Rd  Female 
    481  Wyatt 014523548  Gainesville   Westfield rd Male 
    724 Brittany 551489230  Aldi    Ostrich rd Female 
    100 Giovanni 774451362  Paige    Company ln Male 

最终的结果应该是: 实施例:用户输入参数PersonID = 140

Column_name Page_Num  Line_Num  Element_Num  Data 
    _____________________________________________________________________________ 
    Name   DT-01   200    20    Santana 
    SSN   DT-02   220    10    514819926 
    City   DT-03   300    11   Falls Church 
    StreetName DT-04   350    33    Gane Rd 
    Sex   DT-05   310    51    Female 
    ...   ...   ...    ...    ... 

等..

回答

0

下面将动态逆透视一个数据行,然后执行对联接字段名称与def数据。

如果你想不带过滤器运行此查询,我建议增加A.PersonID顶端SELECT并取出WHERE

我要补充,UNPIVOT将是更好的性能,但使用这种方法,有不需要定义和/或重新设置值。也就是说,表现仍然非常令人尊敬。

Select D.* 
     ,Data=C.Value 
From #Temp A 
Cross Apply (Select XMLData = cast((Select A.* For XML Raw) as xml)) B 
Cross Apply (
       Select Item = attr.value('local-name(.)','varchar(100)') 
         ,Value = attr.value('.','varchar(max)') 
       From B.XMLData.nodes('/row') as X(r) 
       Cross Apply X.r.nodes('./@*') AS N(attr) 
      ) C 
Join #Table D on (C.Item=D.Column_Name) 
Where PersonID=140 

返回

enter image description here

如果它以可视化帮助,CROSS应用Ç生成以下内容:

enter image description here

编辑 - 作为存储过程

CREATE PROCEDURE [dbo].[YourProcedureName](@PersonID int) 

As 

Begin 
    Set NoCount On; 

    Select D.* 
      ,Data=C.Value 
    From YourPersonTableName A 
    Cross Apply (Select XMLData = cast((Select A.* For XML Raw) as xml)) B 
    Cross Apply (
        Select Item = attr.value('local-name(.)','varchar(100)') 
          ,Value = attr.value('.','varchar(max)') 
        From B.XMLData.nodes('/row') as X(r) 
        Cross Apply X.r.nodes('./@*') AS N(attr) 
       ) C 
    Join YourObjectTableName D on (C.Item=D.Column_Name) 
    Where [email protected] 

End 
+0

@BetaData见更新的答案。我添加了一个存储过程。您需要提供YourPersonTableName和YourObjectName –

+0

谢谢,您能否解释Cross在C中的应用,我了解跨应用的用法,但不确定“attr.value”在做什么。你是否将列归属于该数据类型? – BetaData

+0

@BetaData交叉应用B将把行转换成XML Raw,其中每个字段是ATTRIBUTE而不是节点。例如:数据行将如下所示 .....然后交叉应用C将每个属性/值转换成一行。 –