SQL-сервер: конвертировать строки в столбцы - PullRequest
8 голосов
/ 29 апреля 2009

У меня есть таблица с колонками sales(int), month(int). Я хочу получить сумму продаж, соответствующую каждому месяцу. Мне нужен вывод в форме 12 столбцов, соответствующих каждому месяцу, в котором будет отдельная запись, содержащая продажи для каждого столбца (месяца).

Ответы [ 5 ]

10 голосов
/ 29 апреля 2009

Вы должны взглянуть на PIVOT для переключения строк со столбцами. Это предотвращает выбор оператора для каждого месяца. Примерно так:

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
2 голосов
/ 01 мая 2009

Вот альтернативный способ написать сводную точку, которая дает вам немного больше контроля (особенно над именами столбцов). Также немного проще генерировать динамический SQL для.

Это похоже на ответ Робина, но преимущество в том, что вы попадаете в таблицу только один раз:

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;

Я провел некоторое исследование, и похоже, что новый оператор сводки является просто синтаксическим сахаром для этого типа запроса. Планы запросов в конечном итоге выглядят одинаково.

Интересно отметить, что оператор unpivot, похоже, также является синтаксическим сахаром. Например:

Если у вас есть стол вроде:

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

Вы можете написать:

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

И получите непивотированные данные ...

2 голосов
/ 29 апреля 2009

Не красиво ... но это хорошо работает

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 голос
/ 29 апреля 2009

Вы можете сделать это с помощью OLAP . Здесь - еще одна ссылка на документацию MSDN по теме.

С OLAP вы можете создать куб с имеющейся у вас информацией и нужной вам компоновкой.

Если вы не хотите идти по этому пути, вам придется создавать сводные таблицы с .NET, Java, TransacSQL или предпочитаемым вами языком для управления данными SQLServer.

0 голосов
/ 08 апреля 2011

Чтобы легко перенести столбцы в строки с их именами, вы должны использовать XML. В моем блоге это было описано на примере: Ссылка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...