2017-05-19 3 views
1

Ich möchte Werte in Spalten basierend auf einer Gruppe pivotieren. Ich kenne die Werte jedoch vorher nicht.Pivot-Werte für Spalte basierend auf gruppierten Spalten in SQL

Eine Abfrage gibt mir dieses Ergebnis.

Id   Code   EntityId 
----------- ------------ ------------- 
3   22209776  1 
4   143687971 3 
4   143687971 4 
4   143687971 5 
4   143687971 15 
5   143658155 7 
5   143658155 8 

Ich möchte diese Ausgabe

Id   Code   EntityId1  EntityId2  EntityId3  EntityId4 
----------- ------------ ------------- ------------- ------------- ------------- 
3   22209776  1    NULL   NULL   NULL 
4   143687971 3    4    5    15 
5   143658155 7    8    NULL   NULL 

Antwort

1

Wenn Sie nun wissen, wie viele Spalte, die Sie in die gehen zu müssen, Ergebnis, müssen Sie die dynamische T-SQL-Anweisung verwenden, um die PIVOT zu erstellen. Zum Beispiel:

IF OBJECT_ID('tempdb..#DataSource') IS NOT NULL 
BEGIN; 
    DROP TABLE #DataSource; 
END; 

CREATE TABLE #DataSource 
(
    [id] INT 
    ,[Code] INT 
    ,[EntityId] INT 
); 

DECLARE @DynamicTSQLStatement NVARCHAR(MAX) 
     ,@Columns NVARCHAR(MAX); 

DECLARE @MaxColumns INT; 

INSERT INTO #DataSource ([id], [Code], [EntityId]) 
VALUES (3, 22209776 , 1) 
     ,(4, 143687971, 3) 
     ,(4, 143687971, 4) 
     ,(4, 143687971, 5) 
     ,(4, 143687971, 15) 
     ,(5, 143658155, 7) 
     ,(5, 143658155, 8) 
     ,(4, 143687971, 25) 
     ,(4, 143687971, 26); 

-- we need to know how many columns are going to be shown 
SELECT TOP 1 @MaxColumns = COUNT(*) 
FROM #DataSource 
GROUP BY [Code] 
ORDER BY COUNT(*) DESC; 

-- we are building here the following string '[1],[2],[3],[4],[5],[6]'; 
-- this will change depending the input data 
WITH gen AS 
(
    SELECT 1 AS num 
    UNION ALL 
    SELECT num+1 
    FROM gen 
    WHERE num+1<[email protected] 
) 
SELECT @Columns = STUFF 
(
    (
     SELECT ',[EntityId' + CAST([num] AS VARCHAR(12)) + ']' 
     FROM gen 
     FOR XML PATH(''), TYPE 

    ).value('.', 'VARCHAR(MAX)') 
    ,1 
    ,1 
    ,'' 
) 
OPTION (maxrecursion 10000); 

SET @DynamicTSQLStatement = N' 
SELECT * 
FROM 
( 
    SELECT [id] 
      ,[Code] 
      ,[EntityId] 
      ,''EntityId'' + CAST(ROW_NUMBER() OVER(PARTITION BY [Code] ORDER BY [EntityId]) AS VARCHAR(12)) 
    FROM #DataSource 
) DS ([id], [Code], [EntityId], [RowID]) 
PIVOT 
(
    MAX([EntityId]) for [RowID] in (' + @Columns +') 
) PVT;'; 

EXEC sp_executesql @DynamicTSQLStatement; 

enter image description here

0

Sie könnten versuchen, die Pivot-Funktion:

declare @tmp TABLE (id int, Code int, EntityId NVARCHAR(10)) 

insert into @tmp (id, Code, EntityId) 
values (3, 22209776 , 1), 
     (4, 143687971, 3), 
     (4, 143687971, 4), 
     (4, 143687971, 5), 
     (4, 143687971, 15), 
     (5, 143658155, 7), 
     (5, 143658155, 8) 

select 
    pvt.id 
    ,pvt.Code 
    ,[1] as EntityID1 
    ,[2] as EntityID2 
    ,[3] as EntityID3 
    ,[4] as EntityID4 
from ( 
    select 
     id, Code, EntityId 
     ,ROW_NUMBER() over(partition by code order by EntityId) as RowNum 
from 
    @tmp 
) a 
pivot (MAX(EntityId) for RowNum in ([1], [2], [3], [4])) as pvt 
+0

Ich werde versuchen, dass bald. Was ist, wenn EntityId tatsächlich einem anderen Namen entspricht? Ich hätte eigentlich Nvarchar drehen sollen. Möglich? Grundsätzlich etwas anderes als diese MAX (EntityId) tun, aber den Nvarchar-Wert auswählen. – jsgoupil

+0

Können Sie klarstellen, was Sie meinen? – cmn

+0

Ich frage mich, ob EntityId ein VARCHAR sein könnte und ja kann. Deine Antwort funktioniert jedoch, @gotqn hat eine bessere Erklärung bekommen. Danke für deine Antwort! – jsgoupil

Verwandte Themen