以水平格式显示SQL结果

时间:2017-03-07 08:34:43

标签: sql sql-server pivot

我只想改变这一点:

Period  | Department    | Print | Copy
---------------------------------------
201601  | Dept 1        | 10    | 20
201601  | Dept 2        | 20    | 10
201602  | Dept 1        | 30    | 40
201602  | Dept 2        | 40    | 30
201603  | Dept 1        | 50    | 60
201603  | Dept 2        | 60    | 50

进入这个:

Department  | 201601 Print  | 201601 Copy   | 201602 Print  | 201602 Copy   | 201603 Print  | 201603 Copy
------------------------------------------------------------------------------------------
Dept 1      | 10            | 20            | 30            | 40            | 50            | 60
Dept 2      | 20            | 10            | 40            | 30            | 60            | 50

我正在尝试使用PIVOT构建脚本,但我不知道如何在列中显示每个句点的“打印”和“复制”。 此外,由于'Period'的值是未知的,因此我也不能对脚本中的值进行硬编码。

这是我的尝试:

SELECT [Department]
    ,[201601] AS [201601 Copy]
    ,[201602] AS [201602 Copy]
    ,[201603] AS [201603 Copy]
FROM
    (SELECT [Copy], [Period], [Department] from #tempTable) AS ST
PIVOT
    (SUM([Copy]) FOR [Period] IN ([201601],[201602],[201603])) AS PT

以下是使用我的示例数据创建表的脚本:

IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL
    DROP TABLE #tempTable
CREATE TABLE #tempTable(
    [Period] varchar(50)
    ,[Department] varchar(50)   
    ,[Print] int
    ,[Copy] int
)
INSERT INTO #tempTable VALUES 
     ('201601', 'Dept 1', 10, 20)
    ,('201601', 'Dept 2', 20, 10)
    ,('201602', 'Dept 1', 30, 40)
    ,('201602', 'Dept 2', 40, 30)
    ,('201603', 'Dept 1', 50, 60)
    ,('201603', 'Dept 2', 60, 50)

感谢您提前回复。

ANSWER

我研究了收到的答案,最后构建了以下脚本:

DECLARE @sql AS varchar(max);
SELECT @sql = 'SELECT [Department],' + 
    STUFF((
        SELECT DISTINCT
            ',SUM(ISNULL(CASE [Period] WHEN ''' + [Period] + ''' THEN [Print] END, 0)) AS [' + [period] + ' Print]' +
            ',SUM(ISNULL(CASE [Period] WHEN ''' + [Period] + ''' THEN [Copy]  END, 0)) AS [' + [period] + ' Copy]'
        FROM #TempTable
        FOR XML PATH('')
    ), 1, 1, '') +
    'FROM #TempTable 
    GROUP BY [Department]';
PRINT @sql
EXEC(@sql);

4 个答案:

答案 0 :(得分:5)

您可以使用动态SQL查询。

<强>查询

   @keyframes paper-corner {
  0% {
    height:20px;
    width:20px
  }

  50% {
    height:20px;
    width:20px
  }

  60% {
   height:65px;
   width:65px;    
 }

 90% {
   height:65px;
   width:65px;    
 }

  100% {
   height:20px;
   width:20px;    
 }
}

答案 1 :(得分:5)

另一个使用数据透视的动态S​​QL 但是这个使用变量@Columns来生成一个包含列名的字符串

declare @Columns varchar(max);
set  @Columns = STUFF((SELECT ', ' + QUOTENAME([Period] +' Print') + ', ' + QUOTENAME([Period] +' Copy') FROM  #tempTable GROUP BY [Period] FOR  XML PATH(''), TYPE).value('.', 'NVARCHAR(max)') ,1,1,'');

declare @SQL varchar(max);
set @SQL = 'select *
from (
select [Department], [Period] + '' Print'' as Title, [Print] as Value from #tempTable
union all
select [Department], [Period] + '' Copy'' as Title, [Copy] as Value from #tempTable
) q
pivot (sum(Value) for Title in ('+ @Columns +')) p;';

--select @SQL;
exec (@SQL);

答案 2 :(得分:0)

您可以使用ISNULL()和SUM()函数来实现此目的。

SELECT [Department]
        ,SUM(ISNULL(CASE WHEN [Period]='201601' THEN [Print] END,0)) AS [201601 Print]
        ,SUM(ISNULL(CASE WHEN [Period]='201601' THEN Copy END,0)) AS [201601 Copy]
        ,SUM(ISNULL(CASE WHEN [Period]='201602' THEN [Print] END,0)) AS [201602 Print]
        ,SUM(ISNULL(CASE WHEN [Period]='201602' THEN Copy END,0)) AS [201602 Copy]
        ,SUM(ISNULL(CASE WHEN [Period]='201603' THEN [Print] END,0)) AS [201603 Print]
        ,SUM(ISNULL(CASE WHEN [Period]='201603' THEN Copy END,0)) AS [201603 Copy]               
FROM #tempTable
GROUP BY [Department]

答案 3 :(得分:0)

SELECT Department,SUM([201601Print])[201601 Print],SUM([201601Copy])[201601  Copy],SUM([201602Print])[201602 Print],
                 SUM([201602Copy])[201602 Copy],SUM([201603Print])[201603   Print],SUM([201603Copy])[201603 Copy] FROM (
SELECT [Department]
,[201601] AS [201601Copy]
,[201602] AS [201602Copy]
,[201603] AS [201603Copy]
,0 AS [201601Print]
,0 AS [201602Print]
,0 AS [201603Print]
FROM
(SELECT  [Period],[Copy], [Department] from #tempTable) AS ST
PIVOT
(SUM([Copy]) FOR [Period] IN ([201601],[201602],[201603])) AS PT
UNION ALL
SELECT [Department]
,0 AS [201601Copy]
,0 AS [201602Copy]
,0 AS [201603Copy]
,[201601] AS [201601Print]
,[201602] AS [201602Print]
,[201603] AS [201603Print]
FROM
(SELECT  [Period],[Print], [Department] from #tempTable) AS ST
PIVOT
(SUM([Print]) FOR [Period] IN ([201601],[201602],[201603])) AS PT
)A GROUP BY Department