Здесь СФИНА не происходит. Все вызовы DoStuff
будут вызывать
template <typename T, typename...>
void DoStuff(T input) {
input.bar();
}
. Причина этого в том, что
template <typename T, typename>
void DoStuff(T input) {
input.foo();
}
требуется два параметра шаблона, в то время как
template <typename T, typename...>
void DoStuff(T input) {
input.bar();
}
работает для 1 или более параметров шаблона (пустые пакеты могут быть пустыми). Поэтому, когда вы звоните
DoStuff(Foo());
// or
DoStuff(Bar());
//or
DoStuff(Both());
, вы можете вывести только один параметр шаблона, и единственным жизнеспособным кандидатом является
template <typename T, typename...>
void DoStuff(T input) {
input.bar();
}
Если вы использовали
DoStuff<Foo, any_other_type>(Foo());
, то вы получите ошибку неоднозначности, так как она соответствует обоим шаблонам.
Обратите внимание на 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
Вы можете сделать это с OLAP . Здесь есть еще одна ссылка на документацию MSDN по этой теме.
С помощью OLAP вы можете создать куб с имеющейся у вас информацией и нужным макетом.
Если вы не хотите идти таким образом, вам придется создавать сводные таблицы с .NET, Java, TransacSQL или предпочитаемым вами языком для манипулирования данными SQLServer.
Не симпатично ... но это хорошо работает
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]
Вот альтернативный способ написать сводную точку, которая дает вам немного больше контроля (особенно над именами столбцов). Также немного проще генерировать динамический 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 );
И получить непивотированные данные ...