2010-03-31 5 views
4

Je commence juste à apprendre le T-SQL et je pourrais avoir besoin d'aide pour comprendre ce qui se passe dans un bloc de code particulier. J'ai modifié un code à an answer I received in a previous question, et voici le code en question:Que se passe-t-il dans ce code T-SQL? (Concaténant les résultats d'une instruction SELECT)

DECLARE @column_list AS varchar(max) 
SELECT @column_list = COALESCE(@column_list, ',') + 
    'SUM(Case When Sku2=' + CONVERT(varchar, Sku2) + 
    ' Then Quantity Else 0 End) As [' + 
    CONVERT(varchar, Sku2) + ' - ' + 
    Convert(varchar,Description) +'],' 
FROM OrderDetailDeliveryReview 
Inner Join InvMast on SKU2 = SKU and LocationTypeID=4 
GROUP BY Sku2 , Description 
ORDER BY Sku2 

Set @column_list = Left(@column_list,Len(@column_list)-1) 

Select @column_list 

---------------------------------------- 

1 row is returned: 
,SUM(Case When Sku2=157 Then Quantity Else 0 End) As [157 -..., SUM(Case ... 

Le code T-SQL fait exactement ce que je veux, ce qui est de faire un seul résultat sur la base des résultats d'une requête, qui sera ensuite être utilisé dans une autre requête.

Toutefois, je ne peux pas comprendre comment l'instruction SELECT @column_list =... place plusieurs valeurs dans une seule chaîne de caractères en étant dans une instruction SELECT. Sans l'affectation à @column_list, l'instruction SELECT retournerait simplement plusieurs lignes. Comment se fait-il qu'en ayant la variable dans l'instruction SELECT, les résultats soient "aplatis" en une seule valeur? Comment dois-je lire ce T-SQL pour bien comprendre ce qui se passe?

Répondre

3

Dans SQL Server:

SELECT @var = @var + col 
FROM TABLE 

concatène en fait les valeurs. C'est un mode quirks (et je suis actuellement incapable de trouver une référence à la documentation de feature - qui a été utilisée pendant des années dans la communauté SQL Server). Si @var est NULL au début (soit une valeur non initialisée), alors vous avez besoin d'un COALESCE ou ISNULL (et vous utilisez souvent un séparateur):

SELECT @var = ISNULL(@var, '') + col + '|' 
FROM TABLE 

ou ceci pour faire une liste séparée par des virgules, puis supprimer uniquement la virgule principale:

SELECT @var = ISNULL(@var, '') + ',' + col 
FROM TABLE 

SET @var = STUFF(@var, 1, 1, '') 

ou (avec la permission de KM, en se fondant sur la valeur NULL + « » cédant NULL pour éliminer la nécessité d'STUFF pour le premier élément de la liste):

SELECT @var = ISNULL(@var + ',', '') + col 
FROM TABLE 

ou ceci pour faire une liste avec une virgule de début, séparée et de fin:

SELECT @var = ISNULL(@var, ',') + col + ',' 
FROM TABLE 
+1

n'a pas besoin de 'STUFF()' quand vous le faites de cette façon: 'SELECT @ var = ISNULL (@var + ',', '') + col FROM TABLE' –

+0

@KM, ouais, laissez-moi ajouter cette technique. –

+0

il est probablement plus efficace de mettre par défaut @var à la chaîne vide: '' et d'éliminer le ISNULL() fait pour chaque ligne et de faire le STUFF une fois à la toute fin, cependant ... –

1

Vous voudrez regarder dans la fonction COALESCE. Un bon article décrivant ce qui se passe peut être vu here.

+0

@Jon - En regardant dans la fonction 'COALESCE' certainement aidé. Qu'est-ce que c'est sans la fonction 'COALESCE',' NULL' est retourné. Est-ce parce que les chaînes de caractères ne peuvent pas être ajoutées aux valeurs 'NULL'? –

+0

Salut Ben, tout ce qui est ajouté à une valeur nulle aura toujours un résultat nul – Jon

+0

@Ben Le comportement ANSI NULL de McCormack donnera NULL + str -> NULL. Un comportement non-ANSI donnera NULL + str -> str - vous pouvez obtenir ce comportement non standard avec SET CONCAT_NULL_YIELDS_NULL OFF. –

Questions connexes