Pergunta

Eu tenho uma tabela com colunas sales(int), month(int). Quero recuperar soma das vendas correspondentes a cada mês. Preciso ouput em forma de 12 colunas correspondentes a cada mês em que haverá um único registro contendo vendas para para cada coluna (meses).

Foi útil?

Solução

Você deve dar uma olhada PIVOT para comutação de linhas por colunas . Isso evita que uma instrução SELECT para cada mês. Algo parecido com isto:

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

Outras dicas

Não é bonito ... mas isso funciona bem

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]

Aqui está uma forma alternativa de escrever o pivô que lhe dá um pouco mais de controle (especialmente sobre os nomes das colunas). É também um pouco mais fácil para gerar SQL dinâmico para.

É semelhante a resposta de Robin, mas tem a vantagem de apenas bater a mesa uma vez:

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;

Eu fiz algumas investigações, e parece que o novo operador de pivô é apenas açúcar sintaxe para este tipo de consulta. Os planos de consulta acabam procurando idênticas.

Como um aparte interessante, o operador UNPIVOT parece também ser apenas açúcar sintaxe. Por exemplo:

Se você tem uma tabela como:

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

Você pode escrever:

 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 obter os dados não dinamizados ...

Você pode fazê-lo com OLAP . Aqui é um outro link para a documentação MSDN sobre o tema .

Com OLAP, você pode criar um cubo com as informações que você tem, com o layout que você precisa.

Se você não quer ir por esse caminho, você terá que criar tabelas de resumo com .NET, Java, TransacSQL, ou seu idioma preferido para manipular dados SQLServer.

Para colunas facilmente transpor para linhas com seus nomes que você deve usar XML. No meu blog eu estava descrito isso com exemplo: link

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top