Selon Itzik Ben-Gan dans Inside Microsoft SQL Server 2008: T-SQL Querying, SQL Server passe par trois étapes lors de unpivoting une table:
- générer des copies
- éléments Extrait
- Retirer les lignes avec NULLs
Étape 1: Générer des copies
Une table virtuelle est créée avec une copie de chaque ligne de la table orignal pour chaque colonne qui est en cours de non-pivotement. En outre, une chaîne de caractères du nom de colonne est stockée dans une nouvelle colonne (appelez ceci la colonne QuestionName). * Note: J'ai modifié la valeur de l'une de vos colonnes à NULL pour afficher le processus complet.
UserID UserName AnswerTo1 AnswerToQ2 AnswerToQ3 QuestionName
1 John 1 0 1 AnswerToQuestion1
1 John 1 0 1 AnswerToQuestion2
1 John 1 0 1 AnswerToQuestion3
2 Mary 1 NULL 1 AnswerToQuestion1
2 Mary 1 NULL 1 AnswerToQuestion2
2 Mary 1 NULL 1 AnswerToQuestion3
Etape 2: éléments d'extrait
Puis une autre table est créée qui crée une nouvelle ligne pour chaque valeur de la colonne de la source qui correspond à la valeur de chaîne de caractères dans la colonne QuestionName. La valeur est stockée dans une nouvelle colonne (appelez ceci la colonne Response).
UserID UserName QuestionName Response
1 John AnswerToQuestion1 1
1 John AnswerToQuestion2 0
1 John AnswerToQuestion3 1
2 Mary AnswerToQuestion1 1
2 Mary AnswerToQuestion2 NULL
2 Mary AnswerToQuestion3 1
Étape 3: Supprimer les lignes avec NULLS
Cette étape filtre les lignes qui ont été créés avec des valeurs nulles de la colonne de réaction. En d'autres termes, si l'une des colonnes AnswerToQuestion avait une valeur nulle, elle ne serait pas représentée comme une ligne non pivotée.
UserID UserName QuestionName Response
1 John AnswerToQuestion1 1
1 John AnswerToQuestion2 0
1 John AnswerToQuestion3 1
2 Mary AnswerToQuestion1 1
2 Mary AnswerToQuestion3 1
Si vous suivez ces étapes, vous pouvez
- CROSS JOIN toutes les lignes de la table contre chaque AnswerToQuestion nom de colonne pour obtenir des copies de ligne
- alimenter la colonne de réponse basée sur la mise en correspondance la colonne source et QuestionName
- Supprimez les valeurs NULL pour obtenir les mêmes résultats sans utiliser UNPIVOT.
Un exemple ci-dessous:
DECLARE @t1 TABLE (UserID INT, UserName VARCHAR(10), AnswerToQuestion1 INT,
AnswertoQuestion2 INT, AnswerToQuestion3 INT
)
INSERT @t1 SELECT 1, 'John', 1, 0, 1 UNION ALL SELECT 2, 'Mary', 1, NULL, 1
SELECT
UserID,
UserName,
QuestionName,
Response
FROM (
SELECT
UserID,
UserName,
QuestionName,
CASE QuestionName
WHEN 'AnswerToQuestion1' THEN AnswerToQuestion1
WHEN 'AnswerToQuestion2' THEN AnswertoQuestion2
ELSE AnswerToQuestion3
END AS Response
FROM @t1 t1
CROSS JOIN (
SELECT 'AnswerToQuestion1' AS QuestionName
UNION ALL SELECT 'AnswerToQuestion2'
UNION ALL SELECT 'AnswerToQuestion3'
) t2
) t3
WHERE Response IS NOT NULL
Je reçois «colonne nom de question n'existe pas» avec ce – hedgedandlevered
Non, ma requête fonctionne très bien. Vous obtenez cette erreur uniquement en essayant de faire référence à l'alias 'QuestionName' ailleurs dans la requête. Placez cette requête dans une table dérivée et sélectionnez-la, vous pouvez y ajouter des conditions. Vous utilisez SQL Server, n'est-ce pas? – ErikE
Oh, non, j'utilise le SQL normal. N'a pas vu la balise sql-server. Merci, fini par le comprendre en utilisant la réponse de 8kb et la vôtre. – hedgedandlevered