web-dev-qa-db-fra.com

Pivot TSQL sans fonction d'agrégat

J'ai une table comme ça ...

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 d'utiliser 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
105
ctrlShiftBryan

Vous pouvez utiliser l'agrégat MAX, cela fonctionnerait toujours. MAX d'une valeur = cette valeur ..

Dans ce cas, vous pouvez également vous joindre 5 fois à vous-même sur customerid, filtrer par nom de colonne par nom de table Cela peut marcher mieux.

83
gbn

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
138
Charles Bretana

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

Ensuite, je devais utiliser une instruction while et construire l’instruction ci-dessus en tant que varchar et utiliser SQL dynamique. 

Utiliser 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)

Avoir un pour construire @fulltext en utilisant une boucle while et sélectionner les noms de colonne distincts en dehors de la table. Merci pour les réponses.

8
ctrlShiftBryan
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;
7
mr_eclair
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 cela sans éditeur et je n'ai pas exécuté le SQL. J'espère que vous avez l'idée.

6
shahkalpesh

Le PO n'avait pas réellement besoin de pivoter sans agrégation, mais pour ceux d'entre vous qui viennent ici pour savoir comment voir:

requête cte paramétrée sql

La réponse à cette question implique une situation dans laquelle un pivot sans agrégation est nécessaire, de sorte qu'un exemple de cette opération fait partie de la solution.

5
bielawski

Voici un excellent moyen de créer des champs dynamiques pour une requête pivot:

--summarize valeurs à une table tmp

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')
0
user7237698

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
0
Randy Boamah

Essaye ça:

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
0
user3538033