TSQL Pivot без агрегатной функции - PullRequest
112 голосов
/ 27 августа 2009

У меня есть такая таблица ...

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 ]

147 голосов
/ 27 августа 2009

да, но почему !! ??

   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
85 голосов
/ 27 августа 2009

Вы можете использовать агрегат MAX, он все равно будет работать. MAX одного значения = это значение ..

В этом случае вы также можете самостоятельно присоединиться 5 раз по обычному адресу, фильтруя по dbColumnName для каждой ссылки на таблицу. Может получиться лучше.

11 голосов
/ 19 декабря 2013
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;
9 голосов
/ 28 августа 2009

Хорошо, извините за плохой вопрос. ГБН получил меня на правильном пути. Это то, что я искал в ответе.

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 и выбора отдельных имен столбцов из таблицы. Спасибо за ответы.

7 голосов
/ 27 августа 2009
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' 

Редактировать: я написал это без редактора и не запускал SQL. Надеюсь, вы поняли.

6 голосов
/ 17 декабря 2013

ОП на самом деле не нужно было поворачиваться без согласования, но для тех из вас, кто пришел сюда, чтобы узнать, как увидеть:

sql параметризованный запрос cte

Ответ на этот вопрос связан с ситуацией, когда необходим сводный элемент без агрегации, поэтому пример его выполнения является частью решения.

1 голос
/ 01 декабря 2016

Вот отличный способ построить динамические поля для сводного запроса:

- суммировать значения в таблицу 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')
1 голос
/ 26 апреля 2016

Это должно работать:

select * from (select [CustomerID]  ,[Demographic] ,[Data]
from [dbo].[pivot]
) as Ter

pivot (max(Data) for  Demographic in (FirstName, MiddleName, LastName, [Date]))as bro
1 голос
/ 16 апреля 2014

Попробуйте это:

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
...