如何在SQL Server中的两列上进行透视

时间:2018-12-13 10:49:21

标签: sql sql-server tsql pivot multiple-columns

下面是我拥有的数据行:

ID     Code      OtherCol
7      Code1      NULL
7      code2      NULL
2      unk        NULL
4      unk        NULL
3      Code2      NULL
3      Code3      NULL
3      Code5      Other1
5      Code4      NULL
5      Code5      Other2

我正在尝试将此显示为

ID name1 name2 name3 name4 name5 nameunk Othername
2                                unk
3        code2 code3       code5         Other1
4                                unk                    
5                    code4 code5         Other2
7  code1 code2

我能够旋转第一列,但在旋转第二列时遇到问题。

给定的name也有一个code,但是OtherCol下的值是随机的。

3 个答案:

答案 0 :(得分:2)

我建议条件聚合:

public IEnumerable<string> Flattener(object o)
{
    if (o is IEnumerable<string> strings)
    {
        return strings;
    }
    if (o is string s)
    {
       return new[]{s};
    }
    return new[]{"?"};
}

答案 1 :(得分:1)

这是完整的工作示例。您可以对其进行一些更改以匹配您的真实数据。

CREATE TABLE #DataSource
(
    [ID] INT
   ,[Code] VARCHAR(12)
   ,[OtherCol] VARCHAR(12)
);

INSERT INTO #DataSource ([ID], [Code], [OtherCol])
VALUES (7, 'Code1', NULL)
      ,(7, 'code2', NULL)
      ,(2, 'Unk', NULL)
      ,(4, 'Unk', NULL)
      ,(3, 'Code2', NULL)
      ,(3, 'Code3', NULL)
      ,(3, 'Code5', 'Other1')
      ,(5, 'Code4', NULL)
      ,(5, 'Code4', 'Other2');


DECLARE @DynammicTSQLStatement NVARCHAR(MAX)
       ,@DynamicPIVOTColumns NVARCHAR(MAX);


SET @DynamicPIVOTColumns = STUFF
                          (
                                (
                                SELECT ',[' + CAST([value] AS VARCHAR(12)) + ']'
                                FROM 
                                (
                                    SELECT 0
                                         ,DENSE_RANK() OVER (ORDER BY [Code])
                                         ,REPLACE([Code], 'Code', 'name')
                                    FROM #DataSource
                                    WHERE [Code] IS NOT NULL
                                    UNION
                                    SELECT 1
                                          ,1
                                          ,'OtherCol'
                                ) DS ([GroupID],[RowID], [value])
                                ORDER BY [GroupID], [RowID]
                                FOR XML PATH('') ,TYPE
                                ).value('.', 'NVARCHAR(MAX)')
                                ,1
                                ,1
                                ,''
                          );

SET @DynammicTSQLStatement = N'
SELECT *
FROM
(
    SELECT [ID]
          ,[Code]
          ,REPLACE([Code], ''Code'', ''name'')
    FROM #DataSource
    UNION ALL
    SELECT [ID]
          ,[OtherCol]
          ,''OtherCol''
    FROM #DataSource
) DS ([ID], [value], [column])
PIVOT
(
    MAX([value]) FOR [column] IN (' + @DynamicPIVOTColumns + ')
) PVT';

EXEC sp_executesql @DynammicTSQLStatement;

DROP TABLE #DataSource;

enter image description here

答案 2 :(得分:0)

--PIVOT THE TABLE
select ID,[code1],[code2], [code3],[code4],[code5],[Unk]
into #resPivot
from 
(
  select ID, code
  from tblTest
) src
pivot
(
  max(code)
  for code in ([code1], [code2], [code3],[code4],[code5],[Unk])
) piv;

--FIND ALL COLS WHERE OTHER COLUMN have value row 3,5 in your example
SELECT * INTO #distinct FROM tblTest where tblTest.otherCol IS NOT NULL

--PIVOTED RESULT WITH ABOVE TABLE
select distinct #resPivot.ID,[code1], [code2], [code3],[code4],[code5],[Unk],#distinct.otherCol
into #otherCol
from #resPivot  inner join #distinct
on #distinct.id = #resPivot.id 

--THIS IS PIVOTED RESULT WITH ALL RESULTS THAT HAS NO OTHER COL VALUE UNION with OTHER CALL VALUE 
select distinct #resPivot.ID,[code1], [code2], [code3],[code4],[code5],[Unk],tblTest.otherCol 
from #resPivot  inner join tblTest
on tblTest.id = #resPivot.id 
WHERE otherCol IS NULL and tblTest.ID NOT IN (SELECT ID FROM #otherCol)
UNION ALL
Select * from #otherCol

--DROP TEMP TABLES
Drop Table #resPivot
Drop Table #distinct
Drop Table #otherCol

更简单,更快速的版本