Pivot TSQL sans fonction d'agrégation
j'ai une table comme celle-ci...
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
et je veux ça...
est-ce possible avec 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 réponses
vous pouvez utiliser l'agrégat MAX, il fonctionnerait toujours. MAX d'une valeur = valeur..
dans ce cas, vous pouvez aussi vous joindre 5 fois sur customerid, filtrer par dbColumnName par référence de table. Il peut mieux fonctionner.
oui, mais pourquoi !!??
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
ok, désolé pour la pauvre question. gbn m'a mis sur la bonne voie. C'est ce que je cherchais dans une réponse.
SELECT [FirstName], [MiddleName], [LastName], [Date]
FROM #temp
PIVOT
( MIN([Data])
FOR [DBColumnName] IN ([FirstName], [MiddleName], [LastName], [Date])
)AS p
alors j'ai dû utiliser une déclaration while et construire la déclaration ci-dessus comme un varchar et utiliser dynmaic sql.
en utilisant quelque chose comme ça
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)
ayant un pour construire @fulltext en utilisant une boucle while et sélectionnez les noms de colonne distincts hors de la table. Merci pour les réponses.
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: j'ai écrit ceci sans éditeur et n'ai pas exécuté le SQL. Je l'espère, vous obtenez l'idée.
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;
L'OP N'a pas vraiment besoin de pivoter sans accord, mais pour ceux d'entre vous qui viennent ici pour savoir comment voir:
La réponse à cette question suppose une situation où pivot sans l'agrégation est un exemple de faire partie de la solution.
essayez ceci:
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
cela devrait fonctionner:
select * from (select [CustomerID] ,[Demographic] ,[Data]
from [dbo].[pivot]
) as Ter
pivot (max(Data) for Demographic in (FirstName, MiddleName, LastName, [Date]))as bro
Voici une excellente façon de construire des champs dynamiques pour une requête de pivot:
--résumer les valeurs d'un tmp table
declare @STR varchar(1000)
SELECT @STr = COALESCE(@STr +', ', '')
+ QUOTENAME(DateRange)
from (select distinct DateRange, ID from ##pivot)d order by ID
---voir les champs générés
print @STr
exec(' .... pivot code ...
pivot (avg(SalesAmt) for DateRange IN (' + @Str +')) AS P
order by Decile')