programing

SQL 쿼리를 사용하여 쉼표로 구분 된 목록을 만들려면 어떻게합니까?

sourcetip 2021. 1. 16. 11:15
반응형

SQL 쿼리를 사용하여 쉼표로 구분 된 목록을 만들려면 어떻게합니까?


다음과 같은 3 개의 테이블이 있습니다.

  • 응용 프로그램 (ID, 이름)
  • 자원 (ID, 이름)
  • 애플리케이션 리소스 (id, app_id, resource_id)

모든 리소스 이름 테이블을 GUI에 표시하고 싶습니다. 각 행의 한 셀에 해당 리소스의 모든 응용 프로그램 (쉼표로 구분)을 나열하고 싶습니다.

그래서 질문은 모든 리소스를 가져와야하고 각 리소스에 대한 모든 응용 프로그램을 가져와야하므로 SQL에서이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

먼저 리소스에서 선택 *을 실행 한 다음 각 리소스를 반복하고 리소스별로 별도의 쿼리를 수행하여 해당 리소스에 대한 응용 프로그램 목록을 가져 옵니까?

하나의 쿼리에서이 작업을 수행 할 수있는 방법이 있습니까?


DB에 구애받지 않는 방식으로 할 수있는 방법은 없습니다. 따라서 다음과 같이 전체 데이터 세트를 가져와야합니다.

select 
  r.name as ResName, 
  a.name as AppName
from 
  Resouces as r, 
  Applications as a, 
  ApplicationsResources as ar
where
  ar.app_id = a.id 
  and ar.resource_id = r.id

그런 다음 ResName으로 그룹화하는 동안 프로그래밍 방식으로 AppName 을 연결합니다 .


MySQL

  SELECT r.name,
         GROUP_CONCAT(a.name SEPARATOR ',')
    FROM RESOURCES r
    JOIN APPLICATIONSRESOURCES ar ON ar.resource_id = r.id
    JOIN APPLICATIONS a ON a.id = ar.app_id
GROUP BY r.name

SQL Server (2005 이상)

SELECT r.name,
       STUFF((SELECT ','+ a.name
               FROM APPLICATIONS a
               JOIN APPLICATIONRESOURCES ar ON ar.app_id = a.id
              WHERE ar.resource_id = r.id
           GROUP BY a.name
            FOR XML PATH(''), TYPE).value('.','VARCHAR(max)'), 1, 1, '')
 FROM RESOURCES r

SQL Server (2017+)

  SELECT r.name,
         STRING_AGG(a.name, ',')
    FROM RESOURCES r
    JOIN APPLICATIONSRESOURCES ar ON ar.resource_id = r.id
    JOIN APPLICATIONS a ON a.id = ar.app_id
GROUP BY r.name

신탁

Oracle의 문자열 집계 / 연결에 대해 읽는 것이 좋습니다 .


COALESCE를 사용하여 SQL Server에서 쉼표로 구분 된 문자열 작성
http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string

예:

DECLARE @EmployeeList varchar(100)

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

SELECT @EmployeeList

데이터베이스에 구애받지 않는 방식으로이 작업을 수행하는 솔루션이 있는지 모르겠습니다. 어떤 형태의 문자열 조작이 필요할 가능성이 높고 일반적으로 공급 업체마다 다르기 때문입니다.

SQL Server 2005 이상에서는 다음을 사용할 수 있습니다.

SELECT
     r.ID, r.Name,
     Resources = STUFF(
       (SELECT ','+a.Name
        FROM dbo.Applications a
        INNER JOIN dbo.ApplicationsResources ar ON ar.app_id = a.id
        WHERE ar.resource_id = r.id
        FOR XML PATH('')), 1, 1, '')
FROM
     dbo.Resources r

SQL Server 2005 FOR XML PATH구문을 사용하여 하위 항목 (주어진 리소스에 대한 응용 프로그램)을 쉼표로 구분 된 목록으로 나열합니다.

마크


나는 당신이 원하는 것은 다음과 같습니다.

SELECT ItemName, GROUP_CONCAT(DepartmentId) FROM table_name GROUP BY ItemName

MySQL을 사용하는 경우

참고


SQL Server 가정 :

테이블 구조 :

CREATE TABLE [dbo].[item_dept](
    [ItemName] char(20) NULL,
    [DepartmentID] int NULL   
)

질문:

SELECT ItemName,
       STUFF((SELECT ',' + rtrim(convert(char(10),DepartmentID))
        FROM   item_dept b
        WHERE  a.ItemName = b.ItemName
        FOR XML PATH('')),1,1,'') DepartmentID
FROM   item_dept a
GROUP BY ItemName

결과 :

ItemName    DepartmentID
item1       21,13,9,36
item2       4,9,44

나는 우리가 검색하기 위해 다음과 같은 방법으로 쓸 수 있다고 생각합니다 (아래 코드는 단지 예입니다. 필요에 따라 수정하십시오).

Create FUNCTION dbo.ufnGetEmployeeMultiple(@DepartmentID int)
RETURNS VARCHAR(1000) AS

BEGIN

DECLARE @Employeelist varchar(1000)

SELECT @Employeelist = COALESCE(@Employeelist + ', ', '') + E.LoginID
FROM humanresources.Employee E

Left JOIN humanresources.EmployeeDepartmentHistory H ON
E.BusinessEntityID = H.BusinessEntityID

INNER JOIN HumanResources.Department D ON
H.DepartmentID = D.DepartmentID

Where H.DepartmentID = @DepartmentID

Return @Employeelist

END

SELECT D.name as Department, dbo.ufnGetEmployeeMultiple (D.DepartmentID)as Employees
FROM HumanResources.Department D

SELECT Distinct (D.name) as Department, dbo.ufnGetEmployeeMultiple (D.DepartmentID) as 
Employees
FROM HumanResources.Department D

다음 버전의 SQL Server 에서 다음 을 수행 할 수 있습니다.

SELECT r.name,
       STRING_AGG(a.name, ',')
FROM   RESOURCES r
       JOIN APPLICATIONSRESOURCES ar
         ON ar.resource_id = r.id
       JOIN APPLICATIONS a
         ON a.id = ar.app_id
GROUP  BY r.name 

제품의 이전 버전의 경우이 문제에 대한 매우 다양한 접근 방식이 있습니다. 이들에 대한 훌륭한 리뷰는 Transact-SQL에서 행 값 연결 문서에 있습니다.

  • 항목 수를 알 수없는 경우 값 연결

    • 재귀 적 CTE 방법
    • 블랙 박스 XML 메서드
    • 공용 언어 런타임 사용
    • 재귀가있는 스칼라 UDF
    • WHILE 루프가있는 테이블 값 UDF
    • 동적 SQL
    • The Cursor approach
      .
  • Non-reliable approaches

    • Scalar UDF with t-SQL update extension
    • Scalar UDF with variable concatenation in SELECT

MySQL

  SELECT r.name,
         GROUP_CONCAT(a.name SEPARATOR ',')
    FROM RESOURCES r
    JOIN APPLICATIONSRESOURCES ar ON ar.resource_id = r.id
    JOIN APPLICATIONS a ON a.id = ar.app_id
GROUP BY r.name

**


MS SQL Server

SELECT r.name,
       STUFF((SELECT ','+ a.name
               FROM APPLICATIONS a
               JOIN APPLICATIONRESOURCES ar ON ar.app_id = a.id
              WHERE ar.resource_id = r.id
           GROUP BY a.name
            FOR XML PATH(''), TYPE).value('.','VARCHAR(max)'), 1, 1, '')
 FROM RESOURCES r
 GROUP BY deptno;

Oracle

  SELECT r.name,
         LISTAGG(a.name SEPARATOR ',') WITHIN GROUP (ORDER BY a.name)
  FROM RESOURCES r
        JOIN APPLICATIONSRESOURCES ar ON ar.resource_id = r.id
        JOIN APPLICATIONS a ON a.id = ar.app_id
  GROUP BY r.name;

To be agnostic, drop back and punt.

Select a.name as a_name, r.name as r_name
  from ApplicationsResource ar, Applications a, Resources r
 where a.id = ar.app_id
   and r.id = ar.resource_id
 order by r.name, a.name;

Now user your server programming language to concatenate a_names while r_name is the same as the last time.


This will do it in SQL Server:

DECLARE @listStr VARCHAR(MAX)
SELECT @listStr = COALESCE(@listStr+',' ,'') + Convert(nvarchar(8),DepartmentId)
FROM Table
SELECT @listStr

ReferenceURL : https://stackoverflow.com/questions/1817985/how-do-i-create-a-comma-separated-list-using-a-sql-query

반응형