2016-09-30 66 views
-1

我有數據的表像SQL:產生一列

pr  inv comm comm1 comm2 
123 1  10 0  1 
234 1  20 5  10 
345 1  40 16  21 
098 2  23 65  76 
765 2  45 32  0 
981 1  65 87  9 
981 2  45 32  100 

基於值的列我想要的結果作爲

pr comm comm1 comm2  comm comm1 comm2 
     1  1  1   2  2  2 
123  10  0  1  0  0  0 
234  20  5  10  0  0  0 
345  40  16  21  0  0  0 
098  0  0  0  23  65  76 
765  0  0  0  45  32  0 
981  65  87  9  45  32  100 

我的意思是我要產生新列每列inv列值。

+0

究竟您正在使用哪個DBMS?完成上述任務的方法各不相同。一個人無法全部回答。 – Susang

+0

sql server 2014 – chanti

+0

你可以在SQL server中使用PIVOT,我認爲你可以通過使用web來完成,所以請嘗試一次。 https://msdn.microsoft.com/en-us/library/ms177410.aspx我認爲你必須首先檢查你的需求,因爲它不完全是可以做到的。 – Susang

回答

1

如果你不介意去動態。這種方法確實需要輔助函數來將數據轉換爲EAV結構(實體屬性值)。

Declare @YourTable table (PR int,Inv int,Comm int,Comm1 int,Comm2 int) 
Insert Into @YourTable values 
(123,1,10, 0, 1), 
(234,1,20, 5, 10), 
(345,1,40,16, 21), 
(098,2,23,65, 76), 
(765,2,45,32, 0), 
(981,1,65,87, 9), 
(981,2,45,32,100) 

Select PR=Entity 
     ,Inv 
     ,Col = Concat(B.Attribute,'_',Inv) 
     ,B.Value 
Into #Temp 
From @YourTable A 
Cross Apply (Select * from [dbo].[udf-EAV]((Select A.* for XML RAW)) Where Attribute<>'Inv') B 

Declare @SQL varchar(max) = '' 
Select @SQL = @SQL+','+QUOTENAME(Col)+'=max(IIF(Col='''+col+''',Value,0))' From (Select Top 100 Percent Inv,Col from #Temp Group By Inv,Col Order by Inv) A 
Exec('Select PR'[email protected]+' From #Temp Group By PR Order By Pr') 

返回

enter image description here

的UDF

CREATE FUNCTION [dbo].[udf-EAV](@XML xml) 
Returns Table 
As 
Return (
    with cteKey(k) as (Select Top 1 xAtt.value('local-name(.)','varchar(100)') From @XML.nodes('/row') As A(xRow) Cross Apply A.xRow.nodes('./@*') As B(xAtt))  

    Select Entity = xRow.value('@*[1]','varchar(50)') 
      ,Attribute = xAtt.value('local-name(.)','varchar(100)') 
      ,Value  = xAtt.value('.','varchar(max)') 
    From @XML.nodes('/row') As A(xRow) 
    Cross Apply A.xRow.nodes('./@*') As B(xAtt) 
    Where xAtt.value('local-name(.)','varchar(100)') Not In (Select k From cteKey) 
) 
/* 
-- Notes: First Field in Query will be the Entity 
1

起初UNPIVOT數據,然後做一個支點,如果有很多inv好多了使用動態SQL生成並運行您的查詢:

SELECT pr, 
     COALESCE(inv1_comm,0) as inv1_comm, 
     COALESCE(inv1_comm1,0) as inv1_comm1, 
     COALESCE(inv1_comm2,0) as inv1_comm2, 
     COALESCE(inv2_comm,0) as inv2_comm, 
     COALESCE(inv2_comm1,0) as inv2_comm1, 
     COALESCE(inv2_comm2,0) as inv2_comm2 
FROM (
    SELECT pr, 
      'inv'+CAST(inv as nvarchar(max))+'_'+comms as inv_comms, 
      [values] 
    FROM (
    SELECT * 
    FROM YourTable 
    ) as t 
    UNPIVOT (
     [values] FOR comms IN (comm,comm1,comm2) 
    ) as unpv 
) as p 
PIVOT (
    MAX([values]) FOR inv_comms IN (inv1_comm,inv1_comm1,inv1_comm2,inv2_comm,inv2_comm1,inv2_comm2) 
) as pvt 

輸出:

pr inv1_comm inv1_comm1 inv1_comm2 inv2_comm inv2_comm1 inv2_comm2 
98 0   0   0   23   65   76 
123 10   0   1   0   0   0 
234 20   5   10   0   0   0 
345 40   16   21   0   0   0 
765 0   0   0   45   32   0 
981 65   87   9   45   32   100 

說明:

起初UNPIVOT部分

SELECT pr, 
     'inv'+CAST(inv as nvarchar(max))+'_'+comms as inv_comms, 
     [values] 
FROM (
SELECT * 
FROM YourTable 
) as t 
UNPIVOT (
    [values] FOR comms IN (comm,comm1,comm2) 
) as unpv 

生成此:

pr inv_comms values 
123 inv1_comm 10 
123 inv1_comm1 0 
123 inv1_comm2 1 
234 inv1_comm 20 
234 inv1_comm1 5 
234 inv1_comm2 10 
345 inv1_comm 40 
345 inv1_comm1 16 
345 inv1_comm2 21 
etc... 

因此,我們從3(N)列中的一列中獲得所有comms

然後我們通過inv的結果集做PIVOT。

COALESCE需要使NULL值 - 0

評估參數在順序,並返回最初計算結果不是NULL所述第一表達的當前值。

+0

考慮它(使其動態)作爲你的功課。 – gofr1