2011-05-13 5 views
6

J'ai une table avec des numéros de téléphone. Au lieu de cracher une seule ligne pour chaque numéro, je veux retourner une liste de numéros de téléphone séparés par des virgules. Quel est le moyen le plus simple de le faire en SQL? Une boucle while?Sortie d'une liste séparée par des virgules dans T-SQL

+0

duplication possible de [Existe-t-il un moyen de créer une fonction SQL Server pour "joindre" plusieurs lignes d'une sous-requête dans un seul champ délimité?] (Http://stackoverflow.com/questions/6899/is-there- a-way-to-create-a-sql-server-function-to-join-multiple-rows-from-a-sub) –

+0

L'idée de base de cette question a été posée plusieurs fois. Jetez un coup d'œil aux liens fournis dans les réponses ci-dessous. – TKTS

+3

@TKTS - Je ne serais pas surpris si c'est le doublon le plus effréné sur SO. Il semble être demandé au moins une fois par jour, parfois plus souvent. –

Répondre

0

This question a plusieurs bonnes options. J'ai effectivement fait référence à la même question et mis en œuvre une ou plusieurs de ces réponses.

Here est un autre ensemble de bonnes options.

1

Voir ma réponse de question. Il y a deux autres façons de le faire énumérées dans cette question également. COALESCE ou pour le chemin XML devrait faire l'affaire cependant.

Modifier (ajouté ma réponse de la question précédente):

CREATE FUNCTION [dbo].[fn_MyFunction]()RETURNS NVARCHAR(MAX) 
AS 
BEGIN  
    DECLARE @str NVARCHAR(MAX)  
    DECLARE @Delimiter CHAR(2)  
    SET @Delimiter = ', '  
    SELECT @str = COALESCE(@str + @Delimiter,'') + AColumn  
    FROM dbo.myTable  
    RETURN RTRIM(LTRIM(@str)) 
END 
3

Vous pouvez créer une UDF qui ferait quelque chose comme ça

CREATE FUNCTION dbo.GetBirthdays(@UserId INT) 
RETURNS VARCHAR(MAX) 
AS 
BEGIN 
DECLARE @combined VARCHAR(MAX) 
SELECT @combined = COALESCE(@combined + ', ' + colName + ', colName) 
FROM YourTable 
WHERE UserId = @UserId 
ORDER BY ColName 

END 

En gros, cela tire juste toutes les valeurs dans une liste simple.

9

Certaines de ces réponses sont trop compliquées avec des requêtes XML complexes et complexes. Je l'utilise tout le temps:

select @Phones=(
    Select PhoneColumn+',' 
    From TableName 
    For XML Path('')) 
-- Remove trailing comma if necessary 
select @Phones=left(@Phones,len(@Phones)-1) 
1

FWIW J'ai créé une fonction SQL CLR Aggregate. Fonctionne comme un champion!

[Serializable] [ SqlUserDefinedAggregate (Format.UserDefined, Name = "JoinStrings", IsInvariantToNulls = true, IsInvariantToDuplicates = faux, IsInvariantToOrder = false, MaxByteSize = 8000)] public struct JoinStrings: IBinarySerialize { public string Résultat;

public void Init() 
{ 
    Result = ""; 
} 
public void Accumulate(SqlString value) 
{ 
    if (value.IsNull) 
     return; 

    Result += value.Value + ","; 

} 
public void Merge(JoinStrings Group) 
{ 
    Result += Group.Result; 
} 

public SqlString Terminate() 
{ 
    return new SqlString(Result.ToString().Trim(new 

char [] {','})); }

public void Read(System.IO.BinaryReader r) 
{ 
    Result = r.ReadString(); 
} 

public void Write(System.IO.BinaryWriter w) 
{ 
    w.Write(Result.ToString()); 
} } 

Je peux alors l'utiliser comme ceci:

SELECT dbo.JoinStrings(Phone) FROM Phones Where UserID = XXX 
1

En supposant que vous avez une table de clients qui a un identifiant unique et une autre table nommée PHONENUMBERS avec plusieurs numéros de téléphone pour chaque partage de la clientèle le champ ID client en tant que clé étrangère cela fonctionnerait en utilisant une sous-requête corrélée

Select C.ID, C.FirstName, C.LastName, 
(select (STUFF((SELECT ', ' + PhoneNumber from PhoneNumbers P where P.CID = C.ID 
FOR XML PATH('')), 1, 2, ''))) as PhoneNumbers 
from Customers C 
0
Select Unique ID, Replace(Rtrim(Ltrim(Case when [Phone_Number1] is not null Then [Phone_Number1]+' ' Else '' End + 
        Case when [Phone_Number2] is not null Then [Phone_Number2]+' ' Else '' End + 
        Case when [Phone_Number3] is not null Then [Phone_Number3]+' ' Else '' End)),' ',', ') as Phone_numbers 

From MYTable 

Espérons que c'est ce que vous cherchez et je ne sais pas si cela vous aidera si loin après la question.

Questions connexes