2017-03-07 38 views
8

Tek istediğim bu dönüştürmektirgöster SQL sonucu

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 

Ben PIVOT ile senaryoyu oluşturmaya çalışıyordum ama nasıl bilmiyorum Sütunlarda her bir dönemin "Yazdır" ve "Kopyala" öğelerini göstermek için Ayrıca, 'Dönem' değerleri bilinmeyeceğinden, bu nedenle betikteki değeri de kodlayamıyorum. Burada

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 

Ve

benim örnek verilerle tablo oluşturmak için komut dosyasıdır: Önceden herhangi cevap için

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) 

Teşekkür

İşte benim girişimidir.

YANIT Aldığım cevaplar okudu ve son olarak aşağıdaki komut dosyasını oluşturun:

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


SQL tabloları çok farklı hayvanlardır - satır ve sütun genellikle değiştirilebilir değildir. Bu sadece * sunum * amaçları içinse, veritabanında değil, sunum/rapor katmanında bunu yapmak daha iyi olacaktır. –

+0

Cevabınızı bu şekilde gönderin - bir yanıt verin ve sunulan cevapların hiçbirinin probleminizi çözmediğini düşünüyorsanız (daha iyi) kabul edin. –

cevap

5

Bir dinamik sql sorgusu kullanabilirsiniz.

Sorgu

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

Bir çekicilik gibi çalışır, çok teşekkürler. Biraz düzenledim ve son senaryonumu sorgumda gösterdim. – pblyt

0

Bunu kullanarak ISNULL() ve SUM() Fonksiyonlar elde edebilirsiniz.

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

Temiz ve basit sorgunuz için teşekkürler, ancak dinamik SQL kullanılarak gereken dönem değerleri bilinmiyordu. – pblyt

+0

Bu durumda @Ullas kodunu kullanabilirsiniz! – 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

bir pivot kullanan başka dinamik SQL.
Ancak, bu sütun adları ile bir dize oluşturmak için bir değişken @Columns kullanır. Bir e-tabloya yüzeysel benzerliğe rağmen

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

Düzenli cevabınız için teşekkürler @LukStorms, ama sadece 1 değişken kullanan Ullas'ın cevabını seçtiğim için üzgünüm. Keşke ikisini de cevap olarak seçebilirdim! – pblyt