Program Club

쉼표를 구분 기호로 사용하여 여러 행을 하나로 변환

proclub 2020. 10. 30. 21:17
반응형

쉼표를 구분 기호로 사용하여 여러 행을 하나로 변환


내가 발행 SELECT username FROM Users하면 다음 결과가 나타납니다.

사용자 이름
--------
남자
메리

하지만 내가 정말로 필요한 것은 다음 과 같이 모든 값이 쉼표로 구분 된 하나의 행입니다.

폴, 존, 메리

어떻게해야합니까?


이것은 당신을 위해 작동합니다. 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))

 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

이전에 오타가 있었는데 위 작품


여러 접근 방식에 대한 좋은 검토 :

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

기사 복사-

Coalesce는 T-SQL의 문자열 연결에 대한 답이 아닙니다. 저는 수년 동안 COALESCE 함수를 사용하여 T-SQL에서 문자열 연결을 작동시키는 것에 대한 많은 게시물을 보았습니다. 이것은 여기의 예 중 하나입니다 (Readifarian Marc Ridey에서 빌림).

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

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

SELECT @categories

이 쿼리는 매우 효과적 일 수 있지만주의가 필요하며 COALESCE의 사용을 올바르게 이해해야합니다. COALESCE는 두 개 이상의 매개 변수를 사용할 수있는 ISNULL 버전입니다. null이 아닌 매개 변수 목록에서 첫 번째 항목을 반환합니다. 따라서 실제로 연결과 관련이 없으며 다음 코드는 COALESCE를 사용하지 않고 정확히 동일합니다.

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

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

SELECT @categories

그러나 데이터베이스의 순서가 지정되지 않은 특성은이를 신뢰할 수 없게 만듭니다. T-SQL에 연결 함수가 (아직)없는 이유는 이것이 요소의 순서가 중요한 집계이기 때문입니다. 문자열 연결의이 변수 할당 방법을 사용하면, 특히 하위 문자열을 특정 순서로 배치하려는 경우 반환되는 답변에 모든 값이 포함되어 있지 않음을 실제로 알 수 있습니다. 내 컴퓨터에서 ', Bikes, Clothing, Components, Accessories'를 반환하려고 할 때 ', Accessories'만 반환하는 다음을 고려하십시오.

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

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

SELECT @categories

순서를 고려하고 특히 문자열 연결을 위해 SQL2005에 포함 된 메서드를 사용하는 것이 훨씬 좋습니다-FOR XML PATH ( '')

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

최근에 하위 쿼리를 사용할 때 GROUP BY와 DISTINCT를 비교 한 게시물에서 FOR XML PATH ( '') 사용을 시연했습니다. 이것을 살펴보면 하위 쿼리에서 어떻게 작동하는지 알 수 있습니다. 'STUFF'기능은 선행 쉼표를 제거하기 위해서만 있습니다.

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
; 

FOR XML PATH는 하위 쿼리에서 ORDER BY를 사용할 수있는 유일한 상황 중 하나입니다. 다른 하나는 TOP입니다. 이름이 지정되지 않은 열과 FOR XML PATH ( '')를 사용하면 XML 태그없이 곧바로 연결됩니다. 이것은 문자열이 HTML로 인코딩된다는 것을 의미하므로 <문자 (등)가있을 수있는 문자열을 연결하는 경우 나중에 수정해야 할 수 있지만 어느 쪽이든 여전히 문자열을 연결하는 가장 좋은 방법입니다. SQL Server 2005에서.


building on mwigdahls answer. if you also need to do grouping here is how to get it to look like

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-to-build-comma-delimited-string


You can use this query to do the above task:

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

For detail and step by step explanation visit the following link http://oops-solution.blogspot.com/2011/11/sql-server-convert-table-column-data.html


In SQLite this is simpler. I think there are similar implementations for MySQL, MSSql and 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;

A clean and flexible solution in MS SQL Server 2005/2008 is to create a CLR Agregate function.

You'll find quite a few articles (with code) on google.

It looks like this article walks you through the whole process using C#.


you can use stuff() to convert rows as comma separated values

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;

Thanks @AlexKuznetsov for the reference to get this answer.


If you're executing this through PHP, what about this?

$hQuery = mysql_query("SELECT * FROM users");
while($hRow = mysql_fetch_array($hQuery)) {
    $hOut .= $hRow['username'] . ", ";
}
$hOut = substr($hOut, 0, strlen($hOut) - 1);
echo $hOut;

참고URL : https://stackoverflow.com/questions/887628/convert-multiple-rows-into-one-with-comma-as-separator

반응형