programing

SQL Server: 여러 행을 하나의 행으로 결합

golfzon 2023. 4. 9. 22:35
반응형

SQL Server: 여러 행을 하나의 행으로 결합

다음과 같은 SQL 쿼리가 있습니다.

SELECT * 
FROM Jira.customfieldvalue
WHERE CUSTOMFIELD = 12534
AND ISSUE = 19602

그리고 그것이 그 결과입니다.

여기에 이미지 설명 입력

것은 한해 주세요. 것을 STRINGVALUE와 는 콤마로 구분되어 있습니다.

SELECT --some process with STRINGVALUE--
FROM Jira.customfieldvalue
WHERE CUSTOMFIELD = 12534
AND ISSUE = 19602

Araç Listesi (C2, K1 vb.Belgeler; yoksa Ruhsat Fotokopileri), Min. 5
araç plakası için İnternet Sorgusu, Son 3 Yıla Ait Onaylı Yıl Sonu
Bilanço + Gelir Tablosu, Son Yıl (Yıl Sonuna ait) Detay Mizanı, İçinde
Bulunduğumuz Yıla ait Ara Dönem Geçici Vergi Beyannamesi, Bayi Yorum
E-Maili, Proforma Fatura

내가 어떻게 그럴 수 있을까?

몇 가지 방법이 있습니다.

통합된 문자열 값만 반환하려면 이 방법이 빠르고 쉬운 방법입니다.

DECLARE @combinedString VARCHAR(MAX)
SELECT @combinedString = COALESCE(@combinedString + ', ', '') + stringvalue
FROM jira.customfieldValue
WHERE customfield = 12534
    AND ISSUE = 19602

SELECT @combinedString as StringValue 

그러면 결합된 문자열이 반환됩니다.

XML 메서드 중 하나를 사용해 볼 수도 있습니다.

SELECT DISTINCT Issue, Customfield, StringValues
FROM Jira.customfieldvalue v1
CROSS APPLY ( SELECT StringValues + ',' 
              FROM jira.customfieldvalue v2
              WHERE v2.Customfield = v1.Customfield 
                  AND v2.Issue = v1.issue 
              ORDER BY ID 
                  FOR XML PATH('') )  D ( StringValues )
WHERE customfield = 12534
    AND ISSUE = 19602

이를 실현하려면 For XML Path와 STUP을 다음과 같이 조합합니다.

SELECT (STUFF((
        SELECT ', ' + StringValue
        FROM Jira.customfieldvalue
        WHERE CUSTOMFIELD = 12534
        AND ISSUE = 19602
        FOR XML PATH('')
        ), 1, 2, '')
    ) AS StringValue

이지만, SQL 2017 Server 2017, Microsoft SQL Server 2017, Microsoft SQL Server 2017을 할 수 되었습니다.STRING_AGG()의 기능과 한 기능GROUP_CONCAT기능을 합니다.

STRING_AGG(Transact-SQL) 매뉴얼

USE AdventureWorks2016
GO
SELECT STRING_AGG (CONVERT(NVARCHAR(max),FirstName), ',') AS csv 
FROM Person.Person; 

돌아온다

Syed,Catherine,Kim,Kim,Kim,Hazem

MySql에는 GROUP_CONCAT라는 편리한 방법이 있습니다.SQL Server에 해당하는 것은 존재하지 않지만 SQLCLR을 사용하여 직접 작성할 수 있습니다.다행히도 누군가가 이미 당신을 위해 그것을 해줬습니다.

다음으로 쿼리는 다음과 같이 바뀝니다(BTW가 훨씬 좋은 구문입니다).

SELECT CUSTOMFIELD, ISSUE, dbo.GROUP_CONCAT(STRINGVALUE)
FROM Jira.customfieldvalue
WHERE CUSTOMFIELD = 12534 AND ISSUE = 19602
GROUP BY CUSTOMFIELD, ISSUE

, 이 방법은 그룹 내에서 최대 100줄까지 사용할 수 있습니다.그 밖에도 퍼포먼스에 큰 문제가 생깁니다.SQLCLR Aggregate는 중간 결과를 모두 시리얼화해야 하며, 이 결과 많은 작업이 빠르게 누적됩니다.명심해!

도 ★★★★★★★★★★★★★★★★★.FOR XML같은 문제를 겪지 않고 대신 끔찍한 구문을 사용합니다.

listagg 기능을 지원하는 데이터베이스의 경우 다음을 수행할 수 있습니다.

select id, issue, customfield, parentkey, listagg(stingvalue, ',') within group (order by id)
from jira.customfieldvalue
where customfield = 12534 and issue = 19602
group by id, issue, customfield, parentkey

MySQL 내장 함수 group_concat()을 사용하면 원하는 결과를 얻을 수 있습니다.구문은 다음과 같습니다.

SELECT group_concat(STRINGVALUE) 
FROM Jira.customfieldvalue
WHERE CUSTOMFIELD = 12534
AND ISSUE = 19602

위의 명령어를 실행하기 전에 group_concat_max_len의 크기를 늘려야 합니다.그렇지 않으면 출력 전체가 해당 셀에 들어가지 않을 수 있습니다.

group_concat_max_len 값을 설정하려면 다음 명령을 수행합니다.

SET group_concat_max_len = 50000;

따라서 값 50000을 변경할 수 있으며 필요에 따라 값을 더 크게 할 수 있습니다.

CREATE VIEW  [dbo].[ret_vwSalariedForReport]
AS
     WITH temp1 AS (SELECT
     salaried.*,
     operationalUnits.Title as OperationalUnitTitle
FROM
    ret_vwSalaried salaried LEFT JOIN
    prs_operationalUnitFeatures operationalUnitFeatures on salaried.[Guid] = operationalUnitFeatures.[FeatureGuid] LEFT JOIN 
    prs_operationalUnits operationalUnits ON operationalUnits.id = operationalUnitFeatures.OperationalUnitID 
    ), 
temp2 AS (SELECT
    t2.*,
    STUFF ((SELECT ' - ' + t1.OperationalUnitTitle
        FROM
            temp1 t1 
        WHERE t1.[ID] = t2.[ID]  
        For XML PATH('')), 2, 2, '') OperationalUnitTitles from temp1 t2) 
SELECT 
    [Guid],
    ID,
    Title,
    PersonnelNo,
    FirstName,
    LastName,
    FullName,
    Active,
    SSN,
    DeathDate,
    SalariedType,
    OperationalUnitTitles
FROM 
    temp2
GROUP BY 
    [Guid],
    ID,
    Title,
    PersonnelNo,
    FirstName,
    LastName,
    FullName,
    Active,
    SSN,
    DeathDate,
    SalariedType,
    OperationalUnitTitles

declare @maxColumnCount int=0;
 declare @Query varchar(max)='';
 declare @DynamicColumnName nvarchar(MAX)='';

-- table type variable that store all values of column row no
 DECLARE @TotalRows TABLE( row_count int)
 INSERT INTO @TotalRows (row_count)
 SELECT (ROW_NUMBER() OVER(PARTITION BY InvoiceNo order by InvoiceNo Desc)) as row_no FROM tblExportPartProforma

-- Get the MAX value from @TotalRows table
 set @maxColumnCount= (select max(row_count) from @TotalRows)
 
-- loop to create Dynamic max/case and store it into local variable 
 DECLARE @cnt INT = 1;
 WHILE @cnt <= @maxColumnCount
 BEGIN
   set @DynamicColumnName= @DynamicColumnName + ', Max(case when row_no= '+cast(@cnt as varchar)+' then InvoiceType end )as InvoiceType'+cast(@cnt as varchar)+''
      set @DynamicColumnName= @DynamicColumnName + ', Max(case when row_no= '+cast(@cnt as varchar)+' then BankRefno end )as BankRefno'+cast(@cnt as varchar)+''
            set @DynamicColumnName= @DynamicColumnName + ', Max(case when row_no= '+cast(@cnt as varchar)+' then AmountReceived end )as AmountReceived'+cast(@cnt as varchar)+''

      set @DynamicColumnName= @DynamicColumnName + ', Max(case when row_no= '+cast(@cnt as varchar)+' then AmountReceivedDate end )as AmountReceivedDate'+cast(@cnt as varchar)+''


   SET @cnt = @cnt + 1;
END;

-- Create dynamic CTE and store it into local variable @query 
  set @Query='
     with CTE_tbl as
     (
       SELECT InvoiceNo,InvoiceType,BankRefno,AmountReceived,AmountReceivedDate,
       ROW_NUMBER() OVER(PARTITION BY InvoiceNo order by InvoiceNo Desc) as row_no
       FROM tblExportPartProforma
      )
  select
     InvoiceNo
     '+@DynamicColumnName+'
     FROM CTE_tbl
     group By InvoiceNo'

-- Execute the Query
 execute (@Query)

언급URL : https://stackoverflow.com/questions/8005846/sql-server-combining-multiple-rows-into-one-row

반응형