2016-09-30 1 views
-1

i mit Daten eine Tabelle wiesql: Spalten erzeugen, die auf Werte in einer Spalte basiert

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 

möchte ich das Ergebnis als

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 

was ich meine ist, ich neue Spalten zu erzeugen, haben für jeder inv Spaltenwerte.

+0

Welches DBMS verwenden Sie genau? Das Verfahren zum Erfüllen der obigen Aufgabe ist in jedem Fall unterschiedlich. Nicht möglich für alles in einem zu beantworten. – Susang

+0

sql server 2014 – chanti

+0

Sie können PIVOT in SQL-Server verwenden und ich denke, Sie können es mithilfe von Web tun, also bitte versuchen Sie es einmal. https://msdn.microsoft.com/en-us/library/ms177410.aspx Ich denke, dass Sie Ihre Anforderung zuerst überprüfen müssen, weil es nicht genau ist, was getan werden kann. – Susang

Antwort

1

Wenn es Ihnen nichts ausmacht, dynamisch zu gehen. Dieser Ansatz erfordert eine Hilfsfunktion, um Ihre Daten in eine EAV-Struktur (Entity Attribute Value) zu konvertieren.

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') 

Returns

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

Zuerst UNPIVOT Daten tun dann eine PIVOT, wenn es zu viele inv s besser nutzen dynamische SQL sind generieren und führen Sie Ihre Abfrage:

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 

Ausgang:

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 

Erläuterung:

Zuerst UNPIVOT Teil

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 

diese generieren:

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... 

So erhalten wir alle comms in einer Spalte von 3 (N) Spalten.

Dann werden wir PIVOT um inv s Ergebnis-Set erweitert werden.

COALESCE benötigt NULL Werte zu machen - 0

die Argumente auswertet, um und gibt den aktuellen Wert des ersten Ausdrucks, der auf NULL zunächst nicht ausgewertet.

+0

Betrachten Sie es als Ihre Hausaufgaben (es dynamisch zu machen). – gofr1

Verwandte Themen