Этот тип запроса (который транспонирует значения из строк в столбцы) называется сводным запросом (SQL Server) или кросс-таблицей (Access).
Существует два типа сводных запросов (вообще говоря):
- С фиксированным количеством столбцов.
- С динамическим числом столбцов.
SQL Server поддерживает оба типа, но:
- Database Engine (язык запросов: T-SQL) поддерживает напрямую только сводную
запросы с фиксированным числом столбцов (1) и косвенно (2)
- Службы Analysis Services (язык запросов: MDX) поддерживают напрямую оба типа (1 и 2).
Кроме того, вы можете запросить (MDX) источники данных службы анализа из T-SQL, используя функции OPENQUERY / OPENROWSET или используя связанный сервер с именами из четырех частей.
Решения T-SQL (только):
Для первого типа (1), начиная с SQL Server 2005, вы можете использовать оператор PIVOT:
SELECT pvt.*
FROM
(
SELECT Date, Id, Status_ID, Status_Time
FROM Table
) src
PIVOT ( SUM(src.Status_Time) FOR src.Status_ID IN ([1], [2], [3]) ) pvt
или
SELECT pvt.Date, pvt.Id, pvt.[1] AS Lunch, pvt.[2] AS [Break], pvt.[3] Vacation
FROM
(
SELECT Date, Id, Status_ID, Status_Time
FROM Table
) src
PIVOT ( SUM(src.Status_Time) FOR src.Status_ID IN ([1], [2], [3]) ) pvt
Для динамического числа столбцов (2) T-SQL предлагает только косвенное решение: динамические запросы. Сначала вы должны найти все отличные значения от Status_ID, а следующий шаг - построить окончательный запрос:
DECLARE @SQLStatement NVARCHAR(4000)
,@PivotValues NVARCHAR(4000);
SET @PivotValues = '';
SELECT @PivotValues = @PivotValues + ',' + QUOTENAME(src.Status_ID)
FROM
(
SELECT DISTINCT Status_ID
FROM Table
) src;
SET @PivotValues = SUBSTRING(@PivotValues,2,4000);
SELECT @SQLStatement =
'SELECT pvt.*
FROM
(
SELECT Date, Id, Status_ID, Status_Time
FROM Table
) src
PIVOT ( SUM(src.Status_Time) FOR src.Status_ID IN ('+@PivotValues+') ) pvt';
EXECUTE sp_executesql @SQLStatement;