Pregunta

Tengo una tabla con columnas sales (int) , month (int) . Quiero recuperar la suma de ventas correspondiente a cada mes. Necesito salida en forma de 12 columnas correspondientes a cada mes en el que habrá un registro único que contenga ventas para cada columna (mes).

¿Fue útil?

Solución

Debería echar un vistazo a PIVOT para cambiar filas con columnas . Esto evita una declaración de selección para cada mes. Algo como esto:

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

Otros consejos

No es bonito ... pero esto funciona bien

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]

Aquí hay una forma alternativa de escribir el pivote que le da un poco más de control (especialmente sobre los nombres de columna). También es un poco más fácil generar SQL dinámico para.

Es similar a la respuesta de Robin, pero tiene la ventaja de solo golpear la mesa una 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;

Hice algunas investigaciones, y parece que el nuevo operador de pivote es solo sintaxis de azúcar para este tipo de consulta. Los planes de consulta terminan pareciendo idénticos.

Como un lado interesante, el operador no-pivote también parece ser simplemente azúcar de sintaxis. Por ejemplo:

Si tienes una tabla como:

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

Puedes escribir:

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

Y obtenga los datos no divididos ...

Puede hacerlo con OLAP . Aquí hay otro enlace a la documentación de MSDN sobre el tema .

Con OLAP, puede crear un cubo con la información que tiene, con el diseño que necesita.

Si no desea ir por ese camino, tendrá que crear tablas de resumen con .NET, Java, TransacSQL o su idioma preferido para manipular los datos del servidor SQL.

Para transponer fácilmente las columnas en filas con sus nombres, debe usar XML. En mi blog me describieron esto con un ejemplo: Enlace

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top