2017-04-21 77 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將每個屬性/值轉換成一行。 –