2016-06-02 19 views
0

ich eine Tabelle mit Spalte und Werten wie untenSQL Server dynamische Spalten Erstellung

enter image description here

Wie hole ich das Ergebnis wie in der zweiten tabellarischen Spalte mit den dynamischen Spaltennamen als - zunächst mit " prgmg_product_id "und der Rest der Spalte als" Quelle ID 1 "," Quelle ID 2 "," Quelle ID 3 "

+0

Dies wurde tausende Male hier und dem Rest des Internets beantwortet. –

+3

Mögliches Duplikat von [SQL Server dynamische PIVOT-Abfrage?] (Http://stackoverflow.com/questions/10404348/sql-server-dynamic-pivot-query) –

+1

Mögliches Duplikat von [Wie bekomme ich Spaltennamen aus einer Tabelle in SQL Server?] (Http://stackoverflow.com/questions/1054984/how-can-i-get-column-names-from-a-table-in-sql-server) – Pio

Antwort

0

diese mit Dynamic SQL Um das zu erreichen, werden die folgenden helfen:

CREATE TABLE #Prgmg (
    prgmg_product_id INT 
    ,source_id_other INT 
    ); 

INSERT #Prgmg (
    prgmg_product_id 
    ,source_id_other 
    ) 
VALUES (3310,11478) 
    ,(3337,10833) 
    ,(3354,11466) 
    ,(4039,4846) 
    ,(4039,65454) 
    ,(4039,65456); 

DECLARE @DYColumns NVARCHAR(1000) 
    ,@DYSqlQuery NVARCHAR(4000); 

-- CREATE THE COLUMNS REQUIRED 
SET @DYColumns = STUFF((
      SELECT DISTINCT ',' 
        + N'sourceID' 
        + CAST(ROW_NUMBER() OVER (PARTITION BY prgmg_product_id ORDER BY prgmg_product_id, source_id_other) AS NVARCHAR(10))  
      FROM #Prgmg 
      FOR XML PATH('') 
      ), 1, 1, ''); 

-- CREATE THE DYNAMIC SQL AND ADD IN THE CREATED COLUMNS 
SET @DYSqlQuery = ' 
    SELECT prgmg_product_id,' 
     + @DYColumns 
     + ' FROM (
       SELECT prgmg_product_id 
        ,CAST(N''sourceID'' + CAST(ROW_NUMBER() OVER (
         PARTITION BY prgmg_product_id ORDER BY prgmg_product_id, source_id_other 
         ) AS NVARCHAR(10)) AS NVARCHAR(100)) AS Col 
        ,source_id_other 
       FROM #Prgmg S1 
     ) X 
     PIVOT(MIN(source_id_other) FOR Col IN (' + @DYColumns + ')) P' 

EXECUTE sp_executesql @DYSqlQuery; 

Während dies Sie die Lösung bietet, sollten Sie Zeit zu verstehen, die Konzepte verwendet verbringen. Wie zum Beispiel die Erstellung der benötigten Spalten unter Verwendung von ROW_NUMBER und die Art und Weise, wie dies der Verwendung der PIVOT entspricht.

0

Ich hatte ein wenig Zeit, um dies zusammen zu werfen. Ich weiß, dass in der Umgebung von SO ein dynamischer Pivot verwendet wird. Ich interessiere mich nicht sehr für PIVOT in SQL Server. Ich finde die Syntax sehr stumpf. Ich bevorzuge stattdessen eine Kreuztabellenabfrage (auch als bedingte Aggregation bezeichnet). Der zusätzliche Vorteil ist, dass dieser Ansatz fast immer etwas schneller ist als ein dynamischer PIVOT.

Sie müssen auch feststellen, dass mehr als die Hälfte des hier angegebenen Codes das Problem aufbaut. In Zukunft sollten Sie ddl- und Beispieldaten in einem Verbrauchsmaterialformat wie diesem posten. Es macht uns so viel leichter zu helfen.

if OBJECT_ID('tempdb..#Something') is not null 
    drop table #Something 

create table #Something 
(
    prgmg_product_id int, 
    source_id_other int 
) 

insert #Something (prgmg_product_id, source_id_other) values 
(3310, 11478), 
(3337, 10833), 
(3354, 11466), 
(4039, 4846), 
(4039, 65454), 
(4039, 65456) 

declare @StaticPortion nvarchar(2000) = 
    'with OrderedResults as 
    (
     select *, ROW_NUMBER() over(partition by prgmg_product_id order by source_id_other) as RowNum 
     from #Something 
    ) 
    select prgmg_product_id'; 

declare @DynamicPortion nvarchar(max) = ''; 
declare @FinalStaticPortion nvarchar(2000) = ' from OrderedResults Group by prgmg_product_id order by prgmg_product_id desc'; 

with E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)), 
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows 
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max 
cteTally(N) AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4 
) 

select @DynamicPortion = @DynamicPortion + 
    ', MAX(Case when RowNum = ' + CAST(N as varchar(6)) + ' then source_id_other end) as SourceID' + CAST(N as varchar(6)) + CHAR(10) 
from cteTally t 
where t.N <= 
(
    select top 1 Count(*) 
    from #Something 
    group by prgmg_product_id 
    order by COUNT(*) desc 
) 

declare @SqlToExecute nvarchar(max) = @StaticPortion + @DynamicPortion + @FinalStaticPortion; 
exec sp_executesql @SqlToExecute 
+0

Danke mein Freund .. – Ramaswamy