2010-05-25 4 views
0

Chaque exemple d'utilisation de PIVOT dans MSSQL montre aux personnes qui utilisent ceci pour agréger des données. Je suis en train d'exploiter ce nombre à mettre purement et simplement des lignes à colonnescomment faire pivoter des lignes vers des colonnes

Par exemple, considérons les données follwoing

SELECT 11826 ID,cast('64 ' as varchar(1000)) as answer,75098 QuestionID,2785 CollectionID into #temp 
insert into #temp SELECT 11827 ID,cast('Security ' as varchar(1000)) as answer,75110 QuestionID,2785 CollectionID 
insert into #temp SELECT 11828 ID,cast('42 ' as varchar(1000)) as answer,75115 QuestionID,2785 CollectionID 
insert into #temp SELECT 11829 ID,cast('3/23/2010 12:01:00 AM ' as varchar(1000)) as answer,75119 QuestionID,2785 CollectionID 
insert into #temp SELECT 11830 ID,cast('3/25/2010 ' as varchar(1000)) as answer,75120 QuestionID,2785 CollectionID 
insert into #temp SELECT 11898 ID,cast('67 ' as varchar(1000)) as answer,75313 QuestionID,2792 CollectionID 
insert into #temp SELECT 11899 ID,cast('True ' as varchar(1000)) as answer,75314 QuestionID,2792 CollectionID 
insert into #temp SELECT 11900 ID,cast('0 ' as varchar(1000)) as answer,75315 QuestionID,2792 CollectionID 
insert into #temp SELECT 11901 ID,cast('[email protected] ' as varchar(1000)) as answer,75316 QuestionID,2792 CollectionID 

Les résultats devraient produire quelque chose comme

CollectionID [AnswerFor75098]  [AnswerFor75110]  [AnswerFor75115]  [AnswerFor75315]... 
2785    64     Security   42     
2792    Null    Null     Null     67 

J'ai expérimenté avec PIVOT mais je ne suis pas sûr que ce soit la bonne solution. Si oui, quelqu'un at-il un indice que je pourrais utiliser? Je pense que je peux probablement le faire dans une procédure stockée assez cependant, j'essaie d'éviter d'utiliser des curseurs si possible.

Merci pour l'aide

Répondre

1

Ce que vous cherchez est une requête de tableau croisé. Si vous connaissez les numéros de question que vous cherchez à l'avance, vous pouvez le faire comme ceci:

Select CollectionId 
    , Min(Case When Question = 75098 Then Answer End) As AnswerFor75098 
    , Min(Case When Question = 75110 Then Answer End) As AnswerFor75110 
    , Min(Case When Question = 75115 Then Answer End) As AnswerFor75115 
    , Min(Case When Question = 75315 Then Answer End) As AnswerFor75315 
From #Temp 
Group By CollectionId 

Cependant, si ce que vous voulez est de déterminer dynamiquement les colonnes en fonction des questions, alors ce que vous voulez est un tableau croisé dynamique et cela ne peut pas être fait dans SQL Server sans SQL fugly dynamique. Au lieu de cela, vous devriez le faire dans le niveau intermédiaire ou dans un outil de reporting.

+0

Là je vais, compliquant les choses. Je vais essayer cette approche d'abord, puis je vais jouer avec le pivot. – Beta033

1

Une chose que les gens ne réalisent pas quand ils essaient PIVOT est que vous devez connaître vos colonnes et coder en dur les dans la requête. Cela nous amène à penser: «Est-ce vraiment la meilleure façon?

Vous ne pouvez pas écrire une requête SQL à usage général qui ajoute dynamiquement des colonnes en fonction de valeurs de données, même lorsque vous utilisez la syntaxe PIVOT de Microsoft.

PIVOT est encore un peu plus pratique que d'écrire un tas de JOIN s, donc je conseille d'aller avec PIVOT (si vous utilisez exclusivement Microsoft SQL Server).

+0

Oracle 11g + prend en charge la PIVOT et la syntaxe UNPIVOT. Dans ma comparaison limitée de PIVOT vs CASE sur SQL Server 2005, CASE était légèrement plus rapide. J'ai tendance à utiliser les instructions CASE, principalement pour des problèmes de portabilité. –

+0

Cela ne peut pas être fait strictement dans une seule requête SELECT, mais vous pouvez le faire avec un proc stocké ayant un select afin de construire un SQL dynamique qu'il exécute dynamiquement. En fait, je viens de le faire ce matin, en utilisant des idées volées à http://www.sqlprof.com/blogs/sqldev/archive/2008/04/12/pivots-with-dynamic-columns-in-sql-server- 2005-2008.aspx –

0

J'ai fait un SQL rapide pour montrer comment utiliser Pivot avec vos données d'échantillon. Je pense qu'il peut être amélioré pour réaliser ce que vous voulez.

Select CollectionId,[75098],[75110],[75113],[75114],[75115] from 
(Select QuestionID ,CollectionId, answer From #temp group by QuestionID,CollectionId, answer) as ST 
    PIVOT (count(QuestionID) for QuestionID in ([75098],[75110],[75113],[75114],[75115]))as PT 
group by CollectionId,[75098],[75110],[75113],[75114],[75115] 

@community, s'il vous plaît ne hésitez pas à suggérer des modifications à cette suggestion

Questions connexes