2017-03-07 3 views
8

Alles, was ich will, ist diese zu transformieren:anzeigen SQL Ergebnis im Querformat

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 

in dieser:

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 

Ich habe versucht, das Skript mit PIVOT zu bauen, aber ich weiß nicht, wie um sowohl "Drucken" als auch "Kopieren" für jede Periode in den Spalten anzuzeigen. Außerdem, da die Werte von 'Periode' unbekannt sind, kann ich den Wert im Skript nicht fest codieren.

Hier ist mein Versuch:

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 

Und hier ist das Skript für die Tabelle mit meiner Beispieldaten zu erstellen:

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) 

Vielen Dank für jede Antwort im Voraus.

ANTWORT

Ich studierte die eingegangenen Antworten und schließlich die unten stehende Skript bauen:

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); 
+1

Trotz einer oberflächlichen Ähnlichkeit mit einem Tabellenkalkulationsprogramm, sind SQL-Tabellen sehr unterschiedliche Tiere - Zeilen und Spalten im Allgemeinen nicht austauschbar sind. Wenn dies nur für * Präsentation * Zwecke ist, wäre es besser, dies in der Präsentations-/Berichtsebene zu tun, nicht in der Datenbank. –

+0

Veröffentlichen Sie Ihre Antwort als solche - eine Antwort und akzeptieren Sie sie, wenn Sie glauben, dass keine der angebotenen Antworten Ihr Problem löst (besser). –

Antwort

5

Sie eine dynamische SQL-Abfrage verwenden kann.

Abfrage

declare @sql as varchar(max); 
select @sql = 'select [Department],' + stuff((
    select distinct ',max(case [Period] when ' + char(39) + [Period] + char(39) + 
    ' then [Print] end) [' + [period] + ' Print]' 
    + ',max(case [Period] when ' + char(39) + [Period] + char(39) + 
    ' then [Copy] end) [' + [period] + ' Copy]' 
    from #TempTable 
    for xml path('') 
), 1, 1, ''); 

select @sql += ' from #TempTable group by [Department];'; 
exec(@sql); 
+0

Funktioniert wie ein Charme, vielen Dank. Ich habe ein bisschen redigiert und mein letztes Skript in meiner Frage gezeigt. – pblyt

0

Sie können diese mit ISNULL() und SUM() Funktionen erreichen.

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] 
+0

Danke für Ihre saubere und einfache Abfrage, aber die Periodenwerte wären unbekannt, was die Verwendung von dynamischem SQL erforderte. – pblyt

+0

In diesem Fall können Sie @Ullas Code verwenden !!! – balaji

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 
5

Eine weitere dynamische SQL, die einen Drehpunkt verwendet.
Aber dieser verwendet eine Variable @ Columns, um eine Zeichenfolge mit den Spaltennamen zu generieren.

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); 
+0

Dank @LukStorms für Ihre saubere Antwort, aber Entschuldigung, dass ich Ullas 'Antwort wählte, die nur 1 Variable verwendet. Ich wünschte, ich könnte beides als Antwort wählen! – pblyt