2017-05-19 18 views
1

グループに基づいて値を列にピボットする必要があります。しかし、私はあらかじめ値を知っていません。SQLのグループ化された列に基づく列のピボット値

このクエリは私にこの結果を与えます。

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

私は、出力したいと思い、この

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

答えて

1

あなたは今あなたが持ってしようとしているどのように多くの列知っている場合結果、動的T-SQLステートメントを使用してPIVOTを構築する必要があります。たとえば:

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

あなたはピボット機能を使用して試みることができる:

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

私はすぐにそれを試してみましょう。 EntityIdが実際に別の名前に対応する場合はどうでしょうか?私は基本的にnvarcharをピボットする必要があります。可能?基本的に、このMAX(EntityId)以外の何かをしているが、nvarcharの値を選択する。 – jsgoupil

+0

あなたは何を意味するか分かりますか? – cmn

+0

EntityIdがVARCHARである可能性があります。あなたの答えは動作しますが、@gotqnはより良い説明を得ました。ご回答有難うございます! – jsgoupil

関連する問題