2009-04-29 13 views
8

Ho una tabella con colonne sales(int), month(int). Voglio recuperare la somma delle vendite corrispondente a ogni mese. Ho bisogno di uscita in forma di 12 colonne corrispondenti a ciascun mese in cui ci sarà un singolo record contenente vendite per ogni colonna (mese).SQL server: conversione righe in colonne

risposta

10

Si dovrebbe dare un'occhiata a PIVOT per la commutazione le righe con le colonne. Ciò impedisce un'istruzione select per ogni mese. Qualcosa di simile a questo:

DECLARE @salesTable TABLE 
(
    [month] INT, 
    sales INT 
) 

-- Note that I use SQL Server 2008 INSERT syntax here for inserting 
-- multiple rows in one statement! 
INSERT INTO @salesTable 
VALUES (0, 2) ,(0, 2) ,(1, 2) ,(1, 2) ,(2, 2) 
     ,(3, 2) ,(3, 2) ,(4, 2) ,(4, 2) ,(5, 2) 
     ,(6, 2) ,(6, 2) ,(7, 2) ,(8, 2) ,(8, 2) 
     ,(9, 2) ,(10, 2) ,(10, 2) ,(11, 2) ,(11, 2) 

SELECT [0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11] 
FROM 
(
    SELECT [month], sales 
    FROM @salesTable 
) AS SourceTable 
PIVOT 
(
    SUM(sales) 
    FOR [month] IN ([0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11]) 
) AS PivotTable 
+0

si dovrebbe mostrare la normale sintassi di INSERT pre-2008 –

+0

Probabilmente hai ragione, anche se la domanda non menzionava una versione di SQL Server. Aggiornato la mia risposta per notificare al lettore la differenza di sintassi. –

+0

@sahil garg: hai capito? –

2

Non abbastanza ... ma questo funziona bene

SELECT 
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 1) [Sales1], 
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 2) [Sales2], 
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 3) [Sales3], 
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 4) [Sales4], 
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 5) [Sales5], 
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 6) [Sales6], 
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 7) [Sales7], 
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 8) [Sales8], 
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 9) [Sales9], 
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 10) [Sales10], 
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 11) [Sales11], 
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 12) [Sales12] 
1

Si può farlo con OLAP. Here è un altro collegamento alla documentazione MSDN sull'argomento.

Con OLAP, puoi creare un cubo con le informazioni che hai, con il layout che ti serve.

Se non si desidera procedere in questo modo, sarà necessario creare tabelle di riepilogo con .NET, Java, TransacSQL o la lingua preferita per manipolare i dati di SQLServer.

2

Ecco un modo alternativo per scrivere il pivot che ti dà un po 'più di controllo (specialmente sui nomi delle colonne). È anche un po 'più facile generare SQL dinamico per.

E 'simile alla risposta di Robin, ma ha il vantaggio di un solo colpire il tavolo una volta:

select 
    Sales1 = sum(case when Month = 1 then Sales end) 
, Sales2 = sum(case when Month = 2 then Sales end) 
, Sales3 = sum(case when Month = 3 then Sales end) 
-- etc.. 
from SalesTable; 

ho fatto qualche indagine, e sembra che il nuovo gestore del perno è solo zucchero sintassi per questo tipo di query . I piani di query finiscono per sembrare identici.

Come interessante, l'operatore unpivot sembra anche essere semplicemente sintassi zucchero. Per esempio:

Se si dispone di una tabella come:

Create Table Sales (JanSales int, FebSales int, MarchSales int...) 

si può scrivere:

select unpivoted.monthName, unpivoted.sales 
from Sales s 
outer apply (
    select 'Jan', JanSales union all 
    select 'Feb', FebSales union all 
    select 'March', MarchSales 
) unpivoted(monthName, sales); 

e ottenere i dati di pivot ...

0

di trasporre facilmente le colonne in righe con i suoi nomi dovresti usare XML. Nel mio blog sono stato descritto con questo esempio: Link

Problemi correlati