2009-01-18 4 views
31

Étant donné une fonction de table telle que dbo.Split() de "T-SQL: Opposite to string concatenation - how to split string into multiple records", comment puis-je passer plusieurs lignes en tant qu'arguments?Exécuter une fonction table sur plusieurs lignes?

Cela fonctionne:

SELECT * 
FROM dbo.Split 
    (',', (SELECT myColumn FROM Stuff WHERE id = 22268)) 
WHERE ISNULL(s,'') <> '' 

Il retourne:

pn   s 
----------- ----------- 
1   22351 
2   22354 
3   22356 
4   22357 
5   22360 

Mais cela ne:

SELECT * 
FROM dbo.Split 
    (',', (SELECT myColumn FROM Stuff)) 
WHERE ISNULL(s,'') <> '' 

ne le fait:

SELECT * FROM dbo.Split_temp(',', myColumn), Stuff 

The docs dire:

Quand une fonction définie par l'utilisateur qui retourne une table est appelée dans la clause FROM d'une sous-requête, les arguments de la fonction ne peut pas référencer des colonnes de la requête externe.

Le genre de jeu de résultats, je suis à la recherche ressemblerait à quelque chose comme:

id   pn   s 
----------- ----------- ----------- 
22268  1   22351 
22268  2   22354 
22268  3   22356 
22268  4   22357 
22268  5   22360 
24104  1   22353 
24104  2   22355 
24104  3   22356 
24104  4   22358 
24104  5   22360 
24104  6   22362 
24104  7   22364 
. 
. 
. 

Est-il possible du tout (à part, bien sûr, un curseur) pour y parvenir?

(modifier) ​​

Comme demandé par MarlonRibunal, une table d'échantillon pour produire le résultat ressemble au-dessus:

id   myColumn 
----------- ------------------------------------------- 
22268  22351,22354,22356,22357,22360, 
24104  22353,22355,22356,22358,22360,22362,22364, 

id est un int; myColumn est un varchar(max).

Répondre

48

OUTER APPLY:

SELECT Stuff.id 
    ,Results.pn 
    ,Results.s 
FROM stackoverflow_454945 AS Stuff 
OUTER APPLY dbo.Split(',', Stuff.myColumn) AS Results 
WHERE ISNULL(Results.s,'') <> '' 
+0

Génial! Le deuxième "FROM Stuff" a été marqué comme une erreur de syntaxe, mais après avoir supprimé cela, l'instruction a fait exactement ce que je voulais. Je vous remercie. –

+0

À droite, j'ai laissé cela dans mon copier/coller - j'ai testé et corrigé le code ici. –

+0

Pourquoi utiliser 'isnull (Results.s, '') <> ''' quand 'Results.s n'est pas nul' fonctionne aussi et est beaucoup plus concis? – tgandrews

0

Vous pouvez utiliser le comportement de concaténation COALESCE

declare @split varchar(max) 
set @split = '' 

select @split = @split + Coalesce(myColumn + ',' , ' ') 
from Stuff 
WHERE id = 22268 

select * from dbo.Split(',', @Left(@split,len(@split) -1)) 

Je ne sais pas que ce serait mieux que d'utiliser un curseur.

+0

AIUI, ce ne serait pas conserver l'identifiant respectif de la ligne, seule la valeur. –

Questions connexes