Convertir plusieurs lignes en un seul avec la virgule comme séparateur [dupliquer]

StackOverflow https://stackoverflow.com/questions/887628

  •  23-08-2019
  •  | 
  •  

Question

    

Cette question a déjà une réponse ici:

         

Si j'émets SELECT username FROM Users je reçois ce résultat:

username
--------
Paul
John
Mary

mais ce que je vraiment besoin est un ligne avec toutes les valeurs séparées par une virgule, comme ceci:

Paul, John, Mary

Comment puis-je faire?

Était-ce utile?

La solution

Cela devrait travailler pour vous. Testé le chemin du retour vers SQL 2000.

create table #user (username varchar(25))

insert into #user (username) values ('Paul')
insert into #user (username) values ('John')
insert into #user (username) values ('Mary')

declare @tmp varchar(250)
SET @tmp = ''
select @tmp = @tmp + username + ', ' from #user

select SUBSTRING(@tmp, 0, LEN(@tmp))

Autres conseils

 select
   distinct  
    stuff((
        select ',' + u.username
        from users u
        where u.username = username
        order by u.username
        for xml path('')
    ),1,1,'') as userlist
from users
group by username

avait une faute de frappe avant, les travaux ci-dessus

bon examen de plusieurs approches:

http://blogs.msmvps.com/robfarley/2007/04/07/coalesce-is-not-the-answer-to-string-concatentation-in-t-sql/

Article copie -

Coalesce est pas la réponse à la chaîne dans concaténation T-SQL que j'ai vu de nombreux postes au fil des ans sur l'utilisation de la fonction COALESCE pour obtenir la concaténation de chaîne de travail dans T-SQL. Ceci est l'un des exemples ici (empruntés à Readifarian Marc Ridey).

DECLARE @categories varchar(200)
SET @categories = NULL

SELECT @categories = COALESCE(@categories + ',','') + Name
FROM Production.ProductCategory

SELECT @categories

Cette requête peut être très efficace, mais a besoin de soins à prendre, et doit être bien compris l'utilisation de COALESCE. COALESCE est la version de ISNULL qui peut prendre plus de deux paramètres. Il retourne la première chose dans la liste des paramètres qui ne sont pas nuls. Alors, vraiment ça n'a rien à voir avec concaténation, et le morceau de code suivant est exactement la même - sans utiliser COALESCE:

DECLARE @categories varchar(200)
SET @categories = ''

SELECT @categories = @categories + ',' + Name
FROM Production.ProductCategory

SELECT @categories

Mais la nature non ordonnée des bases de données rend ce peu fiable. La raison pour laquelle l'ensemble T-SQL n'a pas (encore) une fonction de concaténer est que c'est un agrégat pour lequel l'ordre des éléments est important. En utilisant cette méthode variable attribution de concaténation de chaîne, vous pouvez effectivement constater que la réponse qui est renvoyée ne possède pas toutes les valeurs, en particulier si vous voulez que les sous-chaînes mises dans un ordre particulier. Considérez ce qui suit, qui, sur ma machine retourne uniquement «Accessoires, quand je voulais revenir », prêt de vélos, vêtements, Composants, Accessoires:

DECLARE @categories varchar(200)
SET @categories = NULL

SELECT @categories = COALESCE(@categories + ',','') + Name
FROM Production.ProductCategory
ORDER BY LEN(Name)

SELECT @categories

Il vaut bien mieux est d'utiliser une méthode qui prend en considération pour, et qui a été inclus dans SQL2005 spécifiquement dans le but de concaténation de chaîne - POUR XML PATH ( « »)

SELECT ',' + Name
FROM Production.ProductCategory
ORDER BY LEN(Name)
FOR XML PATH('') 

Dans le post que j'ai fait récemment comparer GROUP BY et DISTINCT lors de l'utilisation des sous-requêtes, je démontrais l'utilisation de FOR XML PATH ( « »). Jetez un oeil à ceci et vous verrez comment cela fonctionne dans une sous-requête. La fonction « STUFF » est là que pour enlever la principale virgule.

USE tempdb;
GO
CREATE TABLE t1 (id INT, NAME VARCHAR(MAX));
INSERT t1 values (1,'Jamie');
INSERT t1 values (1,'Joe');
INSERT t1 values (1,'John');
INSERT t1 values (2,'Sai');
INSERT t1 values (2,'Sam');
GO

select
    id,
    stuff((
        select ',' + t.[name]
        from t1 t
        where t.id = t1.id
        order by t.[name]
        for xml path('')
    ),1,1,'') as name_csv
from t1
group by id
; 

XML PATH est une des seules situations dans lesquelles vous pouvez utiliser ORDER BY dans une sous-requête. L'autre est vers le haut. Et lorsque vous utilisez une colonne sans nom et FOR XML PATH ( « »), vous obtiendrez une concaténation droite, sans balises XML. Cela ne signifie pas que les chaînes seront codés en HTML, donc si vous concatène des chaînes qui peuvent avoir le caractère <(etc), alors vous devriez peut-être résoudre ce problème par la suite, mais de toute façon, cela est encore le meilleur moyen de cordes concaténer dans SQL Server 2005.

la construction sur la réponse de mwigdahls. si vous avez aussi besoin de regroupement ici comment obtenir à ressembler

group, csv
'group1', 'paul, john'
'group2', 'mary'

    --drop table #user
create table #user (groupName varchar(25), username varchar(25))

insert into #user (groupname, username) values ('apostles', 'Paul')
insert into #user (groupname, username) values ('apostles', 'John')
insert into #user (groupname, username) values ('family','Mary')


select
    g1.groupname
    , stuff((
        select ', ' + g.username
        from #user g        
        where g.groupName = g1.groupname        
        order by g.username
        for xml path('')
    ),1,2,'') as name_csv
from #user g1
group by g1.groupname
DECLARE @EmployeeList varchar(100)

SELECT @EmployeeList = COALESCE(@EmployeeList + ', ', '') + 
   CAST(Emp_UniqueID AS varchar(5))
FROM SalesCallsEmployees
WHERE SalCal_UniqueID = 1

SELECT @EmployeeList

source: http://www.sqlteam.com/article/using -coalesce à accumulation par des virgules-chaîne délimitée

Vous pouvez utiliser cette requête pour faire la tâche ci-dessus:

DECLARE @test NVARCHAR(max)  
SELECT @test = COALESCE(@test + ',', '') + field2 FROM #test
SELECT field2 = @test 

Pour plus de détails et explication étape par étape sur le lien suivant http://oops-solution.blogspot.com/2011/ 11 / SQL-server-convertir-table-colonne-data.html

Dans ce SQLite est plus simple. Je pense qu'il existe des implémentations similaires pour MySQL, MSSQL et Orable

CREATE TABLE Beatles (id integer, name string );
INSERT INTO Beatles VALUES (1, "Paul");
INSERT INTO Beatles VALUES (2, "John");
INSERT INTO Beatles VALUES (3, "Ringo");
INSERT INTO Beatles VALUES (4, "George");
SELECT GROUP_CONCAT(name, ',') FROM Beatles;

Une solution propre et flexible dans MS SQL Server 2005/2008 est de créer une fonction CLR Agregate.

Vous trouverez un bon nombre d'articles (avec le code) sur google .

Il ressemble à cet article vous guide à travers le processus en utilisant C #.

vous pouvez utiliser des trucs () pour convertir les lignes sous forme de valeurs séparées par des virgules

select
EmployeeID,
stuff((
  SELECT ',' + FPProjectMaster.GroupName 
      FROM     FPProjectInfo AS t INNER JOIN
              FPProjectMaster ON t.ProjectID = FPProjectMaster.ProjectID
      WHERE  (t.EmployeeID = FPProjectInfo.EmployeeID)
              And t.STatusID = 1
              ORDER BY t.ProjectID
       for xml path('')
       ),1,1,'') as name_csv
from FPProjectInfo
group by EmployeeID;

Merci pour la référence @AlexKuznetsov pour obtenir cette réponse.

Si vous exécuter ce par PHP, qu'en est-ce?

$hQuery = mysql_query("SELECT * FROM users");
while($hRow = mysql_fetch_array($hQuery)) {
    $hOut .= $hRow['username'] . ", ";
}
$hOut = substr($hOut, 0, strlen($hOut) - 1);
echo $hOut;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top