2017-05-19 37 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