TSQL Pivot без агрегатной функции
у меня есть такая таблица...
CustomerID DBColumnName Data
--------------------------------------
1 FirstName Joe
1 MiddleName S
1 LastName Smith
1 Date 12/12/2009
2 FirstName Sam
2 MiddleName S
2 LastName Freddrick
2 Date 1/12/2009
3 FirstName Jaime
3 MiddleName S
3 LastName Carol
3 Date 12/1/2009
и я хочу этого...
возможно ли это с помощью PIVOT?
CustomerID FirstName MiddleName LastName Date
----------------------------------------------------------------------
1 Joe S Smith 12/12/2009
2 Sam S Freddrick 1/12/2009
3 Jaime S Carol 12/1/2009
9 ответов:
вы можете использовать максимальный агрегат, он все равно будет работать. Макс одного значения = это значение..
в этом случае вы также можете самостоятельно присоединиться 5 раз к customerid, фильтровать по dbColumnName на ссылку на таблицу. Это может сработать лучше.
да, но почему !!??
Select CustomerID, Min(Case DBColumnName When 'FirstName' Then Data End) FirstName, Min(Case DBColumnName When 'MiddleName' Then Data End) MiddleName, Min(Case DBColumnName When 'LastName' Then Data End) LastName, Min(Case DBColumnName When 'Date' Then Data End) Date From table Group By CustomerId
ОК, извините за плохой вопрос. gbn вывела меня на правильный путь. Это то, что я искал в ответе.
SELECT [FirstName], [MiddleName], [LastName], [Date] FROM #temp PIVOT ( MIN([Data]) FOR [DBColumnName] IN ([FirstName], [MiddleName], [LastName], [Date]) )AS p
затем мне пришлось использовать оператор while и построить вышеуказанный оператор как varchar и использовать dynmaic sql.
использовать что-то вроде этого
SET @fullsql = @fullsql + 'SELECT ' + REPLACE(REPLACE(@fulltext,'(',''),')','') SET @fullsql = @fullsql + 'FROM #temp ' SET @fullsql = @fullsql + 'PIVOT' SET @fullsql = @fullsql + '(' SET @fullsql = @fullsql + ' MIN([Data])' SET @fullsql = @fullsql + ' FOR [DBColumnName] IN '+@fulltext SET @fullsql = @fullsql + ')' SET @fullsql = @fullsql + 'AS p' EXEC (@fullsql)
имея возможность построить @fulltext с помощью цикла while и выбрать отдельные имена столбцов из таблицы. Спасибо за ответы.
SELECT main.CustomerID, f.Data AS FirstName, m.Data AS MiddleName, l.Data AS LastName, d.Data AS Date FROM table main INNER JOIN table f on f.CustomerID = main.CustomerID INNER JOIN table m on m.CustomerID = main.CustomerID INNER JOIN table l on l.CustomerID = main.CustomerID INNER JOIN table d on d.CustomerID = main.CustomerID WHERE f.DBColumnName = 'FirstName' AND m.DBColumnName = 'MiddleName' AND l.DBColumnName = 'LastName' AND d.DBColumnName = 'Date'
Edit: я написал это без редактора и не запускал SQL. Я надеюсь, вы поняли идею.
WITH pivot_data AS ( SELECT customerid, -- Grouping Column dbcolumnname, -- Spreading Column data -- Aggregate Column FROM pivot2 ) SELECT customerid, [firstname], [middlename], [lastname] FROM pivot_data PIVOT (max(data) FOR dbcolumnname IN ([firstname],[middlename],[lastname])) AS p;
OP на самом деле не нужно было поворачиваться без согласования, но для тех из вас, кто пришел сюда, чтобы узнать, как увидеть:
SQL параметризованный запрос cte
ответ на этот вопрос связан с ситуацией, когда pivot без агрегации необходим, поэтому пример его выполнения является частью решения.
попробуйте это:
SELECT CUSTOMER_ID, MAX(FIRSTNAME) AS FIRSTNAME, MAX(LASTNAME) AS LASTNAME ... FROM ( SELECT CUSTOMER_ID, CASE WHEN DBCOLUMNNAME='FirstName' then DATA ELSE NULL END AS FIRSTNAME, CASE WHEN DBCOLUMNNAME='LastName' then DATA ELSE NULL END AS LASTNAME, ... and so on ... GROUP BY CUSTOMER_ID ) TEMP GROUP BY CUSTOMER_ID
Это должно работать:
select * from (select [CustomerID] ,[Demographic] ,[Data] from [dbo].[pivot] ) as Ter pivot (max(Data) for Demographic in (FirstName, MiddleName, LastName, [Date]))as bro
вот отличный способ построить динамические поля для сводного запроса:
--суммируйте значения в таблицу tmp
declare @STR varchar(1000) SELECT @STr = COALESCE(@STr +', ', '') + QUOTENAME(DateRange) from (select distinct DateRange, ID from ##pivot)d order by ID
- - - смотрите сгенерированные поля
print @STr exec(' .... pivot code ... pivot (avg(SalesAmt) for DateRange IN (' + @Str +')) AS P order by Decile')